2
votes

I have attempted to make a file to read a text file that contains CSVs. For some reason however some of the Fscanfs do not return a value but some do.

FILE* reader;
char OptionOne[30]="";
char OptionTwo[30]="";
char OptionThree[30]="";
char OptionFour[30]="";
char answer[1]="";
char CorrectAnswer[1];
char Question[51];

reader = fopen("C:\\Users\\Finley\\Desktop\\Programming\\QuizMachine\\QuizMachine\\fscanf_questions.txt", "r");

if (reader == NULL)
{
    printf("Unable to Open File: %s\n", FileName);
}

fscanf(reader, "%[^,],", Question);
fscanf(reader, "%[^,],", OptionOne);
fscanf(reader, "%[^,],", OptionTwo);
fscanf(reader, "%[^,],", OptionThree);
fscanf(reader, "%[^,],", OptionFour);
fscanf(reader, "%[^,],", answer);

Why does the first fscanf return a value but all the others not return a value. I cannot see anything and they all seem the same with the same formating File formatting is like this:

What function do you use to open a file?,fscanf,fclose,fopen,main,3

Which of the following is not a variable type?,int,float,char,string,4

3
So I changed what you suggested but now it gives me the error stack around variable three corrupted. But the first two do give valuesAwkwardowl
@Awkwardowl It would help to know the formatting of the file.Daniel Kleinstein
Updated to include the formatting of the .txt file.Awkwardowl
It might be a copy+paste error, but your first line should end in a comma for your program to work (in addition to the correction in my answer).Daniel Kleinstein
Where should the comma be?Awkwardowl

3 Answers

1
votes
  1. Need to use buffers of adequate size. The answer, as a string needs at least 2 char.@Daniel

  2. fscanf() should limit input to prevent buffer corruption. The width specifier is typically 1 less than the size of the buffer.

    char Question[51];   
    fscanf(reader, "%50[^,],", Question);
    
  3. The result of fscanf() should be checked.

    if (fscanf(reader, "%50[^,],%29[^,],%29[^,],%29[^,],%29[^,],%1s", 
        Question, OptionOne, OptionTwo, OptionThree, OptionFour, answer) != 6) {
      Handle_Bad_input();
    }
    
  4. Do not use "%[^,]" for the last value if input does not have a following ',', else fscanf() will read the next line.

  5. Suggest leading each "[^,]" with a space to skip leading white-space.

    if (fscanf(reader, " %50[^,], %29[^,], %29[^,], %29[^,], %29[^,],%1s", 
    
  6. Even better: Read the line with fgets() and then scan the buffer.

    char buf[200];
    if (fgets(buf, sizeof buf, reader) == NULL) Handle_IOErrorOrEOF();
    if (sscanf(buffer, "%50[^,],%29[^,],%29[^,],%29[^,],%29[^,],%1s", 
        Question, OptionOne, OptionTwo, OptionThree, OptionFour, answer) != 6) {
      Handle_Bad_input();
    }
    
0
votes

Your buffer for answer is too small, so fscanf is writing too much into it leading to corruption.

You gave it a size of only one character, but fscanf will write two characters into it: the character you wanted, 3, and the null character, \0.

Increasing the buffer size to 2 solves the problem.

0
votes
this line: fscanf(reader, "%[^,],", Question); (and those like it) 
have a couple of problems. 
1) should always check the returned value from a input I/O statement
   to assure the conversion was successful 
2) the format string is missing the type conversion, in this case 's'
this line: fscanf(reader, "%[^,],", answer); will fail if the line does not end in a ','


"Why does the first fscanf return a value but all the others not return a value." 
ans: 1) because the ' ' after the comma is not consumed
     2) use a leading ' ' in the format strings to consume white space
        this will also consume an trailing '\n' on each line
     3) a type specifier is NOT optional in a format string, use 's'
     3a) I would have read in the 'answer' as a char using '%c' for a format conversion
         and only created a char, not a char array.
     4) to avoid buffer overruns, 
        include the 'size-1' optional part of each format  conversion,
        just in case some string length is = or greater than the 
        receiving buffer

"I cannot see anything and they all seem the same with the same formating
File formatting is like this:"
ans: where is the file formatting info?

this line: printf("Unable to Open File: %s\n", FileName); 
the variable FileName is not set. 
suggest setting char * FileName = C:\\Users\\Finley\\Desktop\\Programming\\QuizMachine\\QuizMachine\\fscanf_questions.txt‌​" 
and using 'FileName' in the fopen() statement. 

this line: printf("Unable to Open File: %s\n", FileName); 
after this line, should insert 'exit(EXIT_FAILURE);
rather than continue in the program, trying to use that NULL file descriptor pointer 

this line: char answer[1]=""; 
will be a problem as the input is being read in as strings, 
so even for a single char string, there still needs to be
room for the trailing '\0'

this line: fscanf(reader, "%[^,],", answer);
1) fails if each line of the input file, including the last line,
   does not end in ','