【问题标题】:fscanf csv in C. Value not assignedC中的fscanf csv。未分配值
【发布时间】:2015-01-28 07:29:45
【问题描述】:

我试图创建一个文件来读取包含 CSV 的文本文件。然而出于某种原因,有些 Fscanfs 不返回值,但有些却返回。

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);

为什么第一个 fscanf 返回一个值,但所有其他 fscanf 都没有返回一个值。我看不到任何东西,它们看起来都一样,格式相同 文件格式是这样的:

你用什么函数来打开文件?,fscanf,fclose,fopen,main,3

以下哪个不是变量类型?,int,float,char,string,4

【问题讨论】:

  • 所以我改变了你的建议,但现在它给了我围绕变量 3 损坏的错误堆栈。但前两个确实给出了值
  • @Awkwardowl 了解文件的格式会有所帮助。
  • 更新为包含 .txt 文件的格式。
  • 这可能是复制+粘贴错误,但您的第一行应该以逗号结尾以使您的程序正常工作(除了我的答案中的更正)。
  • 逗号应该在哪里?

标签: c string file csv scanf


【解决方案1】:
  1. 需要使用足够大的缓冲区。答案,作为一个字符串至少需要2个char.@Daniel

  2. fscanf() 应限制输入以防止缓冲区损坏。宽度说明符通常比缓冲区的大小小 1。

    char Question[51];   
    fscanf(reader, "%50[^,],", Question);
    
  3. 应该检查fscanf()的结果。

    if (fscanf(reader, "%50[^,],%29[^,],%29[^,],%29[^,],%29[^,],%1s", 
        Question, OptionOne, OptionTwo, OptionThree, OptionFour, answer) != 6) {
      Handle_Bad_input();
    }
    
  4. 如果输入没有后续',',则不要使用"%[^,]" 作为最后一个值,否则fscanf() 将读取下一行。

  5. 建议在每个"[^,]" 前加一个空格以跳过前导空格。

    if (fscanf(reader, " %50[^,], %29[^,], %29[^,], %29[^,], %29[^,],%1s", 
    
  6. 更好的是:使用fgets() 读取,然后扫描缓冲区。

    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();
    }
    

【讨论】:

  • @Awkwardowl 现在您可以对所有个您认为有用且好的答案/问题进行投票。
【解决方案2】:

answer 的缓冲区太小,所以 fscanf 写入太多会导致损坏。

您只给了它一个字符的大小,但fscanf 会在其中写入 两个 字符:您想要的字符 3 和空字符 \0

将缓冲区大小增加到 2 即可解决问题。

【讨论】:

  • 将答案的大小增加到两个它可以工作,但是现在选项四变成了“他跟随不是变量..”,这是第二个问题的一部分。
  • @Awkwardowl 在我的机器上,将缓冲区大小更改为 2 并运行您的代码会得到 OptionFour == "main"
  • 所以我的机器有问题?知道我该如何解决它吗?
  • 您确定.txt 文件和您正在运行的代码与您在问题中包含的内容完全相同吗?并且不要忘记在文件中的 3 之后包含一个逗号。或者将最后一个 fscanf 说明符更改为 %[^,]
【解决方案3】:
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 ','

【讨论】:

    猜你喜欢
    • 2016-11-24
    • 2011-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-29
    • 2015-02-09
    相关资源
    最近更新 更多