| | |
Help reading a text file of any size
Please support our C advertiser: Programming Forums - DaniWeb Sister Site
![]() |
•
•
Join Date: May 2008
Posts: 5
Reputation:
Solved Threads: 0
Hi,
I really need some help with this project. I'm currently a beginning C student working on a wheel of fortune program. For this program a random phrase must be chosen from a text file; the same phrase cannot also be used again during the game (there are three rounds). I've started to work on this, but I'm really stuck. I think I need to have a loop with fgets instead but other than that I'm clueless Please help me. Thanks. The test text file had 43 lines that why rand is with 43
I really need some help with this project. I'm currently a beginning C student working on a wheel of fortune program. For this program a random phrase must be chosen from a text file; the same phrase cannot also be used again during the game (there are three rounds). I've started to work on this, but I'm really stuck. I think I need to have a loop with fgets instead but other than that I'm clueless Please help me. Thanks. The test text file had 43 lines that why rand is with 43
C Syntax (Toggle Plain Text)
int initialize_array(char phrase[], char puzzle[], char clue[]){ FILE* phraseFile; /*input file*/ char temp[100]; /*temporary array*/ int line; /*line from which word and clue are chosen*/ size_t i=0; /*counter for loop*/ int len; /*length of line from file*/ line=rand()%43; /*randomization of line*/ phraseFile = fopen("clues.txt", "r"); /*opens file*/ if (!phraseFile) { fprintf(stderr, "Oops - file not opened !\n"); /*if there is error in opening file program is exited*/ exit(1); } while(line--){ fgets(temp, 100, phraseFile); /*gets line and stores in temp*/ } len=strlen(temp); if(temp[len-1]=='\n') temp[len-1]=0; /*places the null terminating character after word*/ /*separates clues from word*/ strcpy(clue,strtok(temp, "%")); char tmp[WORD_LENGTH]; strcpy(tmp,strtok(NULL,"%")); strcpy(phrase, tmp + 1); strcpy(puzzle,phrase); /*strcpy(puzzle,phrase);*/ while(i<strlen(puzzle)){ if(isalpha(puzzle[i])){ puzzle[i] = '*'; /*hides word*/ } ++i; } fclose(phraseFile); /*closes file*/ return i; }
The hard part is working out how to get a random line from the file when you don't know how many lines there are. One way is to read the file once and count the lines, then use that count to pick a random number. A cooler way is a survivor method. Read lines and use a random test to pick between two lines. The one you picked is the survivor. When you get to the end of the file, the survivor will be randomly picked from all of the lines:
It gets kind of inefficient if you ask for a lot of random lines though. The best solution is to keep the whole file in memory and just use random indexes if it's small enough.
C Syntax (Toggle Plain Text)
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> char *getLine(FILE *fp, char line[], size_t limit); void getRandomLine(const char *filename, char line[], size_t limit); int main() { char line[1024]; int i; srand((unsigned)time(NULL)); /* Get 10 random lines from the file */ for (i = 0; i < 10; ++i) { getRandomLine("test.txt", line, sizeof line); printf("%s\n", line); } } char *getLine(FILE *fp, char line[], size_t limit) { char *result = fgets(line, limit, fp); if (result != NULL) { /* Strip the newline character */ char *nl = strchr(line, '\n'); if (nl != NULL) *nl = '\0'; } return result; } void getRandomLine(const char *filename, char line[], size_t limit) { FILE *fp = fopen(filename, "r"); if (fp != NULL) { /* Get the first line as the first survivor */ if (getLine(fp, line, limit) != NULL) { char *temp = (char*)malloc(limit); /* Survivor method starting with the first 2 lines */ while (getLine(fp, temp, limit) != NULL) { if (rand() % 2 == 0) strcpy(line, temp); } /* Clean up resources */ free(temp); fclose(fp); } } }
Last edited by Radical Edward; May 2nd, 2008 at 12:28 pm.
If at first you don't succeed, keep on sucking until you do succeed.
•
•
Join Date: May 2008
Posts: 5
Reputation:
Solved Threads: 0
I was thinking of doing it the first way described. Here is what I've done so far, but it isn't working. Someone please help!
C Syntax (Toggle Plain Text)
int initialize_array(char phrase[], char puzzle[], char clue[]){ FILE* phraseFile; /*input file*/ char temp[100]; /*temporary array*/ char line[100]; /*line from which word and clue are chosen*/ size_t i=0; /*counter for loop*/ int len; /*length of line from file*/ int count; int x=0; phraseFile = fopen("clues.txt", "r"); /*opens file*/ if (!phraseFile) { fprintf(stderr, "Oops - file not opened !\n"); /*if there is error in opening file program is exited*/ exit(1); } count=0; while(fgets(temp, 100, phraseFile)!=NULL){ ++count; } x=rand()%count+1; len=strlen(temp); if(temp[len-1]=='\n') temp[len-1]=0; /*places the null terminating character after word*/ /*separates clues from word*/ strcpy(clue,strtok(temp, "%")); char tmp[WORD_LENGTH]; strcpy(tmp,strtok(NULL,"%")); strcpy(phrase, tmp + 1); strcpy(puzzle,phrase); /*strcpy(puzzle,phrase);*/ while(i<strlen(puzzle)){ if(isalpha(puzzle[i])){ puzzle[i] = '*'; /*hides word*/ } ++i; } fclose(phraseFile); /*closes file*/ return i; }
You count the lines, but you don't go back and get the random line. Your function will always pick the last line in the file. This is what you want:
C Syntax (Toggle Plain Text)
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> int main() { FILE *fp = fopen("test.txt", "r"); char line[1024]; int count = 0; int r; srand((unsigned)time(NULL)); while (fgets(line, sizeof line, fp) != NULL) ++count; r = rand() % count; // Start over rewind(fp); // Only read r lines while (--r >= 0) fgets(line, sizeof line, fp); puts(line); return 0; }
If at first you don't succeed, keep on sucking until you do succeed.
well, for one thing:
you've got your types switched. not really going to make a difference (size_t is typically #defined as a long int) but still...
if this basic stuff is wrong, i wonder how much more typos and cut-and-paste errors are lurking.
C Syntax (Toggle Plain Text)
size_t i=0; /*counter for loop*/ int len; /*length of line from file*/
if this basic stuff is wrong, i wonder how much more typos and cut-and-paste errors are lurking.
sure. instead of using "rewind", merely close the file, then reopen it exactly as you did the first time.
either way you start at the beginning of the file. rewind is just a nicer way to do it.
PS: dont be afraid to try new functions. especially if they're part of standard ANSI C libraries. rewind is part of the <stdio.h> library.
it's not some sort of secret 33rd level Grand Poobah Royal Order of Ancient Waterbuffalo thing.
either way you start at the beginning of the file. rewind is just a nicer way to do it.
PS: dont be afraid to try new functions. especially if they're part of standard ANSI C libraries. rewind is part of the <stdio.h> library.
it's not some sort of secret 33rd level Grand Poobah Royal Order of Ancient Waterbuffalo thing.
Last edited by jephthah; May 3rd, 2008 at 1:12 am.
![]() |
Similar Threads
- Read text file contents per line (C++)
- c++ reading text file (C++)
- C++ Reading from a text file (C++)
- C: - reading in from text (C++)
- file size (C++)
- Reading an array from a file (Java)
- reading a file into code (Java)
- Stack Queue Fstream (C++)
Other Threads in the C Forum
- Previous Thread: finding factorial of a number.
- Next Thread: how to reverse a string
| Thread Tools | Search this Thread |
* ansi api array arrays bash binarysearch calculate centimeter changingto char character convert copyanyfile copypdffile createcopyoffile createprocess() csyntax directory dynamic fflush file floatingpointvalidation fork forloop frequency getlasterror getlogicaldrivestrin givemetehcodez graphics gtkgcurlcompiling gtkwinlinux hardware highest homework i/o ide inches initialization intmain() iso km license linked linkedlist linux linuxsegmentationfault list logical_drives loopinsideloop. lowest match matrix microsoft motherboard mqqueue multi mysql oddnumber odf open opendocumentformat openwebfoundation pdf pointer pointers posix power program programming pyramidusingturboccodes read recursion recv recvblocked repetition reversing scanf scheduling segmentationfault send shape single socketprogramming stack standard strchr string strings suggestions test testautomation unix urboc user variable whythiscodecausesegmentationfault win32api windows.h windowsapi






