fscanf功能如何工作?

时间:2015-02-01 18:26:59

标签: c

有人可以告诉我fscanf如何处理这个特定的例子(也就是EOF所代表的)。代码有效,但我不理解它背后的过程。

#include <stdio.h>
#include <stdlib.h>
#define LEN 20

int main()
{ FILE *in;
  float average;
  char name[LEN];
  char surname[LEN];
  int grade, n_grades; //n_grades is the total number of grades a person has//  

  in = fopen("grades.txt","r");
  if(in == NULL){
    fprintf(stderr,"error fopen(): Failed to open file grades.txt.\n");
    exit(EXIT_FAILURE);
   }


   while(fscanf(in,"%s",name) != EOF){
       fscanf(in,"%s",surname);
       n_grades = 0;
       average = 0.0;


       while( !feof(in) && fscanf(in,"%d",&grade)>0 ){
    n_grades++;
    average += grade;
    }


    if(n_grades >0)
        average /= n_grades;
    printf("%s %s %.2f\n", name, surname, average);  
   }
   fclose(in);
   return 0;
}

grades.txt看起来像这样:

Steve Stevenson 2 9 4 3 2
John Johnson 2 11 5 3 
Jack Jacskon 22 1 4 5

我不明白这个while循环是如何工作的。 fscanf如何准确知道何时读入哪个字符串?它是如何知道一行的结束时间以及如何进行下一行的?

3 个答案:

答案 0 :(得分:3)

你必须专注于你在那里的双循环:

while(fscanf(in,"%s",name) != EOF){
  fscanf(in,"%s",surname);
  while( !feof(in) && fscanf(in,"%d",&grade)>0 ){
    n_grades++;
  }
}

EOF代表End Of File,因此第一个循环将继续,直到找到文件的末尾,即直到文件指针到达文件末尾。

现在请记住,您的文件包含以下数据:Steve Stevenson 2 9 4 3 2

因此,第一次尝试读取名称,如果尚未达到EOF,则表示您读取了一个名称并在name中分配了该名称。在这里你读史蒂夫。

现在这个fscanf(in,"%s",surname);将读取文件in中当前行的第二个字符串指向(注意%s,这表示我们希望读取一个字符串)。您阅读史蒂文森并将其分配给surname

然后,在第二段时间,您阅读,直到您到达EOF AND ,直到您读取整数。如果您查看fscanf()的参考号,您会看到:

  

返回值   成功时,该函数返回成功填充的参数列表的项数。由于匹配失败,读取错误或文件结束的范围,此计数可以匹配预期的项目数或更少(甚至为零)。

     

如果在读取时发生读取错误或达到文件结尾,则设置正确的指示符(feof或ferror)。并且,如果在成功读取任何数据之前发生任何一次,则返回EOF。

因此,当您读取换行符时,您将读取零整数,因此您将退出循环。

这样你最终会解析所有文件。

根据herescanf()的示例精神,您可以重新编写代码:

while(fscanf(in,"%19s",name) != EOF) {

为了避免溢出。这里20是你的数组的大小。

答案 1 :(得分:1)

fscanf()的原型是

int fscanf(FILE *stream, const char *format, ...)

在您的代码中

fscanf(in,"%s",name)

因此格式说明符确保文件中的第一个字符串被读取为name。我希望你知道在遇到空格之前%s如何工作。

现在文件指针指向文件中的下一个字符串,下一个字符串的读取方式与surname类似,然后我们继续查看字符串后面的整数。

fscanf(in,"%d",&grade);

请注意,fscanf()会返回成功扫描的项目数,当出现错误或EOF时返回EOF。

答案 2 :(得分:0)

你可以把fscanf看成是一个函数,它根据第三个参数是从文件而不是键盘输入的。如果是标准输入则需要键盘输入。当从文件中读取空间字符时,它会停止并返回它已读取的字符,直到空格。