14 Replies - 2309 Views - Last Post: 01 January 2009 - 01:11 AM
#1
How to randomly select a word from a file and display it
Posted 19 December 2008 - 03:47 PM
I using C and not C++.
Can anyone advise me how to select a word RANDOMLY from a file (e.g. 30 words) and display it?
I only know how to select the whole text. Something like this,
fp=fopen("textfile.txt","r");
while(fscanf(fp,"%d %s %lf %c", &number, name, &number, &gender)!=EOF)
printf().....
Thank you.
Replies To: How to randomly select a word from a file and display it
#2
Re: How to randomly select a word from a file and display it
Posted 19 December 2008 - 04:15 PM
//something like this:
int messageNumber;
int count;
string message;
ifstream in;
//srand(time(NULL)); seed in main()
in.open("filename.txt");
in >> count;
for(int i = 0; i < rand()%messageNumber+1; i++)
{
getline(in, message);
}
cout << message;
#3
Re: How to randomly select a word from a file and display it
Posted 19 December 2008 - 06:00 PM
srand(time(NULL)); int quote = 0; int filesize = 0; quote = rand() % filesize;
That was so poorly written, but still.
This post has been edited by Hyper: 19 December 2008 - 06:01 PM
#4
Re: How to randomly select a word from a file and display it
Posted 19 December 2008 - 08:09 PM
Here's my thought. Choose the first line. Read the next line, there is a 1/2 chance you want to replace the prior line with the current one. For the next line, 1/3, then 1/4, and so on. I'm not sure of the mathematical validity of this approach, but a quickly mocked up program for sampling seems to prove out the method.
Here's the code. Sorry for such a complete solution, but I didn't think it would be clear any other way.
#include <stdio.h>
#include <string.h>
#include <time.h>
#define MAX_STRING_SIZE 1000
int main() {
char str[MAX_STRING_SIZE], pick[MAX_STRING_SIZE];
FILE *fp;
int readCount = 0;
srand(time(NULL));
fp = fopen("test.txt", "r");
if(fp) {
if (fgets(pick, MAX_STRING_SIZE, fp) != NULL) {
readCount = 1;
while(fgets(str, MAX_STRING_SIZE, fp) != NULL) {
if ( (rand() % ++readCount)==0) {
strcpy(pick, str);
}
// printf("%d\t%s", readCount, str);
}
}
}
fclose(fp);
printf("%s\n", pick);
}
Hope this helps.
Ah, hell, here's my test, too, if anyone is interested:
#include <stdio.h>
#include <time.h>
#define POOL_SIZE 20
#define SAMPLE_SIZE 10000
int main() {
int hits[POOL_SIZE];
int i, n, pick, count;
srand(time(NULL));
for(i=0; i<POOL_SIZE; i++) { hits[i] = 0; }
for(i=0; i<SAMPLE_SIZE; i++) {
pick = 0;
count = 1;
for(n=1; n<POOL_SIZE; n++) {
if ( (rand() % ++count)==0) {
pick = n;
}
}
hits[pick] = hits[pick] + 1;
}
for(i=0; i<POOL_SIZE; i++) {
printf("%d\t%d\t%f\n", i, hits[i], hits[i]/(float)SAMPLE_SIZE);
}
return 0;
}
#5
Re: How to randomly select a word from a file and display it
Posted 20 December 2008 - 09:56 AM
baavgai, on 19 Dec, 2008 - 07:09 PM, said:
Here's my thought. Choose the first line. Read the next line, there is a 1/2 chance you want to replace the prior line with the current one. For the next line, 1/3, then 1/4, and so on. I'm not sure of the mathematical validity of this approach, but a quickly mocked up program for sampling seems to prove out the method.
Here's the code. Sorry for such a complete solution, but I didn't think it would be clear any other way.
#include <stdio.h>
#include <string.h>
#include <time.h>
#define MAX_STRING_SIZE 1000
int main() {
char str[MAX_STRING_SIZE], pick[MAX_STRING_SIZE];
FILE *fp;
int readCount = 0;
srand(time(NULL));
fp = fopen("test.txt", "r");
if(fp) {
if (fgets(pick, MAX_STRING_SIZE, fp) != NULL) {
readCount = 1;
while(fgets(str, MAX_STRING_SIZE, fp) != NULL) {
if ( (rand() % ++readCount)==0) {
strcpy(pick, str);
}
// printf("%d\t%s", readCount, str);
}
}
}
fclose(fp);
printf("%s\n", pick);
}
Hope this helps.
Ah, hell, here's my test, too, if anyone is interested:
#include <stdio.h>
#include <time.h>
#define POOL_SIZE 20
#define SAMPLE_SIZE 10000
int main() {
int hits[POOL_SIZE];
int i, n, pick, count;
srand(time(NULL));
for(i=0; i<POOL_SIZE; i++) { hits[i] = 0; }
for(i=0; i<SAMPLE_SIZE; i++) {
pick = 0;
count = 1;
for(n=1; n<POOL_SIZE; n++) {
if ( (rand() % ++count)==0) {
pick = n;
}
}
hits[pick] = hits[pick] + 1;
}
for(i=0; i<POOL_SIZE; i++) {
printf("%d\t%d\t%f\n", i, hits[i], hits[i]/(float)SAMPLE_SIZE);
}
return 0;
}
Hi baavgai,
Thank you for your advice. Appreciate it greatly.
I tried to compile it and manage to randomly select a word from a file with several words.
However, I'm facing another problem now.
I'm actually doing a hangman program, it's almost 90% completed after I used your RAND code.
As I tried to display the number of words for a player to guess in the form of '***', \0 is also being read and there is always an extra *. My code as follow,
while(a[n]!=NULL) n++;
for(i=0;i<n;i++) c[i]='*';
printf("c=%s\n",c);
Note: 'a' is a word being selected from the file.
Could you advise on this case? Thanks a lot.
#6
Re: How to randomly select a word from a file and display it
Posted 20 December 2008 - 10:08 AM
for(int i = 0; a[i] != '\0'; i++)
{
printf("*"); //or whatever
}
#7
Re: How to randomly select a word from a file and display it
Posted 20 December 2008 - 07:43 PM
KYA, on 20 Dec, 2008 - 09:08 AM, said:
for(int i = 0; a[i] != '\0'; i++)
{
printf("*"); //or whatever
}
KYA, on 20 Dec, 2008 - 09:08 AM, said:
for(int i = 0; a[i] != '\0'; i++)
{
printf("*"); //or whatever
}
Hi KYA,
Thank you for the reply.
It does not solve the problem.
I'm not sure why but there is always an extra 1 or 2 * when I tried to display the number of characters.
Do you have a solution for it?
If the last word of the file is being selected, the number of * will display correctly though. Is it due to the method of putting those words in the file like should I include ',' or something?
#8
Re: How to randomly select a word from a file and display it
Posted 20 December 2008 - 08:37 PM
#9
Re: How to randomly select a word from a file and display it
Posted 21 December 2008 - 06:44 AM
baavgai, on 19 Dec, 2008 - 07:09 PM, said:
Um, correct me if I'm wrong, but you can use seekg to set it to the end of the file without ever having to "know" the end of the file, then check where it's at, no? I can vaguely remember reading on that a while back.
#10
Re: How to randomly select a word from a file and display it
Posted 21 December 2008 - 07:26 AM
#11
Re: How to randomly select a word from a file and display it
Posted 21 December 2008 - 07:49 AM
KYA, on 20 Dec, 2008 - 07:37 PM, said:
HI KYA,
Thanks. The code that I used to store and get the array is as follow.
#define MAX_STRING 20
srand(time(NULL));
fp=fopen("word2.txt","r");
if(fp) {
if (fgets(a, MAX_STRING, fp) != NULL) {
flag=1;
while(fgets(str, MAX_STRING, fp) != NULL) {
if ( (rand() % ++flag)==0) {
strcpy(a, str);
}
}
}
}
fclose (fp);
Thanks.
** Edit **
#12
Re: How to randomly select a word from a file and display it
Posted 30 December 2008 - 01:55 PM
KYA, on 21 Dec, 2008 - 06:26 AM, said:
Quote
These constants can be combined eg bin_open_file("example.bin", IOS_IN | IOS_OUT)
IOS_IN allow read operations
IOS_OUT allow write operations
IOS_APP appends to a file
IOS_TRUNC current content is discarded
IOS_ATE starts at the end of the file
I was researching my own question earlier last night. Here's the answer:
Open a file with ios_ate, use tellg(); to get the file pointer (which'll be (obviously) at the end), now you have a limit in which you can randomize in (within the files length).
It's quite simple, and effective!
Sorry for the late post.
Hope this helps (if it does, remember to click the little green button that says "This Post Was Helpful!")!
#13
Re: How to randomly select a word from a file and display it
Posted 30 December 2008 - 08:18 PM
long ftell(FILE *) --> gives the current position in the file
int fseek(FILE *, int, int) --> moves the current position in stream [first arg] to N [second arg] places from an origin [last arg], where the origins are as follows:
SEEK_SET --> offset to beginning of file
SEEK_CUR --> current location in buffer
SEEK_END --> end of file
so the simple solution would be:
FILE * fin = fopen("file name", "r"); // open file
do
{
fseek(fin, 0, SEEK_END); // find the end of the file
fseek(fin, -1 * (rand() % ftell(fin)), SEEK_END); // move back random characters
while(!isspace(fgetc(fin) && !feof(fin)); // find the first white space
while(isspace(fgetc(in) && !feof(fin)); // find the start of the word
fseek(fin, -1, SEEK_CUR); // step back, stream is now at the start of the random word
}
while(feof(fin)); // if the first white space was NULL / EOF, try again
-Jerome
#14
Re: How to randomly select a word from a file and display it
Posted 30 December 2008 - 08:35 PM
Hyper, on 30 Dec, 2008 - 02:55 PM, said:
It's quite simple, and effective!
Makes sense, for a specific case.
What if my file is a list of quotes, or simple comma separated values. Your method makes sense if all records are exactly the same length. If it's not a static record structure, then if you use the filesize to choose a position in the file, you're preferring larger records and failing random.
The goal is to "select a word RANDOMLY from a file". My assumption is that the words will not be padded for size and are separated by new lines. If this is the case, your approach is not random and adds some complexity.
#15
Re: How to randomly select a word from a file and display it
Posted 01 January 2009 - 01:11 AM
baavgai, on 30 Dec, 2008 - 07:35 PM, said:
Hyper, on 30 Dec, 2008 - 02:55 PM, said:
It's quite simple, and effective!
Makes sense, for a specific case.
.........
The goal is to "select a word RANDOMLY from a file".
You'd stated earlier (read your posts) you were unaware of how to obtain the full filesize so you could grab between X and X (beginning to ending), which is what I was answering. Unless I mis understood what you'd meant by that.
If you wanted to grab a random quote from a list inside of a file, you'd first off want to do what I'd posted regarding the files size (so you don't try to get text from another file), secondly, you'd want to check for a return line, if one's found, quit reading. If it's an unformatted file - but still cleartext - then the user is making it much harder and more difficult, and should change his ways. If the user does not, then he can build a case-specific solution to that unformatted (no enters, and not binary format) file.
Either way: Welcome.
|
|

New Topic/Question
Reply




MultiQuote






|