1

I'm just trying to get fscanf to read all the characters in a file, along with all the words, but whenever I try to run a whileloop on the file I opened twice it doesn't seem to work? It only seems to be able to use fscanfon a file one time. I found a work around where I can scan the same file twice except I need to open the file a 2nd time for this to work. How can I use fscanf on the same instance of a file twice?

/*Description: Program will open a file named Story.txt
           then counts the number of words and characters
           and prints them out */

int main(){

char word[225]; // will be used to hold words (array of chars)
char c; // will be used to hold chars
int wordCount = 0; // will be used to hold the number of words in the file
int charCount = 0; // will be used to hold the number of chars in the file

FILE* wordFile = fopen("Story.txt","r"); // opens the file Story.txt for counting words

printf("Words: "); // indicates that the following outout will be the words of the file

while(fscanf(wordFile,"%s",&word)==1){ // a loop to scan the file for all the words in it until the end of the file
    printf(" %s ",word); // prints out the word in the given cycle
    wordCount = wordCount + 1; // keeps count of the words the loop has scanned up till now
}

fclose(wordFile); // closes wordFile and frees the memory
FILE* charFile = fopen("Story.txt","r"); // opens file Story.txt for counting chars

printf("\n\nChars: "); // indicates the following output will be the chars of the file

while(fscanf(charFile,"%c",&c)==1){ // a loop to scan the file for all the chars in it until the end fot he file
    if(c!=' '){ // will check if the char is a space, if it is it will not count it
        printf(" %c ",c); // prints out the char for the given cycle
        charCount = charCount + 1; // keeps count of the chars the loop has scanned up till now
    }
}

fclose(charFile); // closes charFile and frees the memory

printf("\n\nWord count: %d and Char count: %d",wordCount,charCount-1); // prints out the word count and char count

return 0;
}

As you can see i have to create two instances of the file or else it will not work. The first instance is called wordFile and the 2nd instance is called charFile. Here's the thing though: Both loops work, it's just that I can't use them on the same file twice. How can I make it so that I will only need to open one instance of the file and then use it to count both the words and the chars in it?

Things I tried: adding the space as suggested here didn't work: C: Multiple scanf's, when I enter in a value for one scanf it skips the second scanf (i searched fscanf but scanf is all that came up so i went off of that).

Another work around that I found strange: if i use wordFilein the 2nd while loop to search for chars it works, the only problem is I have to declare fclose(wordFile); right before it's used in the while loop. I thought fclosewas suppose to close the file and make it unusable? Anyways that worked but what I really want is to use use one instance of the file to read all the chars and strings in it.

Community
  • 1
  • 1
user7839375
  • 31
  • 2
  • 7
  • 1
    C != C++. If this is C++, you should use C++ constructs and don't tag C, if this is C, don't tag C++. – crashmstr Apr 26 '17 at 15:43
  • 2
    If that is what you want, you can read the string and chars at the same time. Read char by char, when you encounter a space, start a new word but continue adding it to the chars. But really in your program you aren't reading the chars in, but reading the char and outputting it... – Evan Carslake Apr 26 '17 at 15:48
  • 1
    `rewind(wordFile);` between passes? – Phil Brubaker Apr 26 '17 at 15:49
  • 1
    It's safer for you to set the buffer size in the `fscanf` format argument. 225 chars should be big enough, but it's still better to be safe than sorry: `fscanf(wordFile, "%224s", &word)` – Elias Van Ootegem Apr 26 '17 at 15:50
  • I'm not sure what the issue is. Once you `fscanf` your pointer is moved. In your 1st loop after, your word count, do a `strlen` to get the charCount. – jiveturkey Apr 26 '17 at 15:50
  • I know there's other ways of doing this but I **need** to do it this way. I need to use a loop to get the strings and a loop to get the chars and in those loop I need to print them out. I just want to understand why I can't use the same file twice to do this. I can't use anything else but what I already have in my code. Thanks for the suggestions though, again not trying to get you guys to do this for me I'm just asking one thing: How can I use the same file twice in both loops? – user7839375 Apr 26 '17 at 16:05
  • What is the longest word in "Story.txt"? – chux - Reinstate Monica Apr 26 '17 at 16:36
  • `fclose(wordFile); FILE* charFile = fopen("Story.txt","r");` --> `rewind(wordFile);` – chux - Reinstate Monica Apr 26 '17 at 16:37
  • @chux I can only use what's already in my code sorry so I wouldn't be able to use 'rewind', thank you for your answer though. Also, the longest word in "Story.txt" is "Something" – user7839375 Apr 26 '17 at 16:43
  • you can eliminate the extra open/close calls and the second FILE* variable by calling `fseek( wordFile, 0, SEEK_SET );` or `rewind( wordFile );` – user3629249 Apr 27 '17 at 21:14

2 Answers2

1

Do something like below - the lazy way of course

char word[225]; 
char c; 
int wordCount = 0; 
int charCount = 0; 

FILE* wordFile = fopen("Story.txt","r"); 

printf("Words: "); 

while(fscanf(wordFile,"%s",word)==1){  // word gives the address not &word
    wordCount = wordCount + 1; 
}

printf("%d\n",wordCount);

fseek(wordFile,0,SEEK_SET); // setting the file pointer to point to the beginning of file

printf("Chars: "); 

while(fscanf(wordFile,"%c",&c)==1){ 
    if(c!=' '&& c!='\n' && c!='\t'){ 
        charCount = charCount + 1; 
    }
}
printf("%d\n",charCount);
fclose(wordFile);  // Closing the file once for all

return 0;
sjsam
  • 21,411
  • 5
  • 55
  • 102
  • thank you I understand now, but why do I need to set it to the beginning of the file? Is this just how 'fscanf' works, so every time I want to scan the entire file I need to set it back to the beginning? – user7839375 Apr 26 '17 at 22:42
  • `so every time I want to scan the entire file I need to set it back to the beginning? ` - YES ! But this is a very lazy approach as I already mentioned. A better option would be count the number of characters in each string, isn't it? – sjsam Apr 27 '17 at 02:41
  • @user7839375, it has nothing to do with `fscan()` but rather the concept of the `current file pointer` which indicates the location in the file where a read or write operation will be preformed. each call to `fscan()` advances that 'current file pointer` through the file by the number of bytes read. So after the first loop is completed, the `current file pointer` will indicate the end of the file. a call to `rewind()` or `fseek( wordFile, 0, SEEK_SET);` will move the `current file pointer` back to the beginning of the file – user3629249 Apr 27 '17 at 21:19
0
fscanf(wordFile,"%s",&word);

The variable "word" is the pointer to the first element of your array (string), so here you are scanning the address not the value. You should rather use:

fscanf(wordFile,"%s",word);