【问题标题】:Fscanf or Fgets? Reading a file line after lineFscanf 还是 Fgets?逐行读取文件
【发布时间】:2012-06-23 09:50:13
【问题描述】:

我必须用 C 编写一个程序来读取一个包含多行文本的文件,每行包含两个变量:一个数字 (%f) 和一个字符串:

EX: file.txt
============
24.0 Torino
26.0 Milano
27.2 Milano
26.0 Torino
28.0 Torino
29.4 Milano

这是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main (int argc, char *argv[])
{
    int r, line = 0, found = 0;
    float temp, t_tot = 0;
    char loc[32];


    FILE *fp;

    fp = fopen(argv[1], "r");

    if (fp == NULL)
    {
        printf ("Error opening the file\n\n'");
        exit(EXIT_FAILURE);
    }

    if (argc == 3)
    {
        r = fscanf(fp, "%f %s\n", &temp, loc);

        while (r != EOF)
        {
            line++;

            if (r == 2)
            {
                if(strcmp(argv[2], loc) == 0)
                {
                    t_tot += temp;
                    found++;
                }
            }
            else
                printf ("Error, line %d in wrong format!\n\n", line);
        }

        printf ("The average temperature in %s is: %.1f\n\n", argv[2], (t_tot/found);
    }

}

程序需要读取所有行并找到我在argv[2] 上写的城市。它会告诉我那个城市的平均温度,如果文件中的一行格式错误,它会通知我。

程序对我来说是正确编译的,但它没有在屏幕上输出任何东西......我该如何解决这个问题?在这种情况下使用fscanf 是正确的还是fgets 更好?

我是学生,所以请给我一个“学术”的方法来解决它:)

【问题讨论】:

    标签: c fgets scanf


    【解决方案1】:

    几件事。

    首先,您必须使用 fclose()。
    其次,您的代码需要 fscan() 文件中的每一行。不仅在 while() 循环之前,而且在每个 while 循环内,您都必须 fscan() 进行下一次迭代。
    第三,您不是在计算平均温度,而是在计算找到的所有温度的总和。通过在最后一个 printf() 中将“t_tot”更改为“(t_tot / found)”来解决此问题。

    最后,我不确定你为什么没有得到任何输出。您的输入就像“myprogram file.txt Milano”对吗?为我工作。无论如何,这是您的(编辑过的)代码:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main (int argc, char *argv[])
    {
        int r, line = 0, found = 0;
        float temp, t_tot = 0;
        char loc[32];
    
        FILE *fp;
        fp = fopen(argv[1], "r");
    
        if (fp == NULL)
        {
            printf ("Error opening the file\n\n'");
            exit(EXIT_FAILURE);
        } else {
    
            if (argc == 3)
            {
                r = fscanf(fp, "%f %s\n", &temp, loc);
                while (r != EOF)
                {
                    line++;
                    if (r == 2)
                    {
                        if(strcmp(argv[2], loc) == 0)
                        {
                            t_tot += temp;
                            found++;
                        }
                    }
                    else
                        printf ("Error, line %d in wrong format!\n\n", line);
                    r = fscanf(fp, "%f %s\n", &temp, loc);
                }
                printf ("The average temperature in %s is: %.1f\n\n", argv[2], (t_tot / found));
            }
    
        fclose(fp);
    
        }
    }
    

    【讨论】:

      【解决方案2】:

      您的代码没有像应有的那样在循环中调用fscanf:读取完成一次,然后程序要么在文件为空时立即存在,要么无限循环。

      您应该将fscanf 的调用移动到while 循环内。一种典型的编码方式是将赋值放在循环头中,如下所示:

      while ((r = fscanf(fp, "%f %s\n", &temp, loc)) != EOF) {
          ...
      }
      

      【讨论】:

      • 感谢您的回答。我才意识到我的错误!如果我想用 fgets 而不是 fscanf 做另一个解决方案,我该怎么做?
      • @l_core 你需要改变一些东西:首先,你需要一个fgets 的缓冲区;那么您将在循环中将EOF 的检查替换为NULL 的检查;最后,您需要手动解析缓冲区,找到第一个空格,将初始部分提供给atof,然后将其余部分复制到strdup
      【解决方案3】:

      您必须将 fscanf 行放在 while 循环中

          while (1)
          {
              r = fscanf(fp, "%f %s\n", &temp, loc);
              if( r == EOF ) 
                 break;
              .........................
          }
      

      最后关闭文件

      如果你使用 fgets 改变如下

        char s[256];
        while( fgets( s, 256, fp) != NULL )
        {
           sscanf( s, "%f %s", &temp, loc);
           .............
        }
      

      【讨论】:

        【解决方案4】:

        像这样修改代码...只需在 while 语句中添加另一个 fscanf。

        if (argc == 3)
        {
         r = fscanf(fp, "%f %s\n", &temp, loc);
          while(r != EOF )
        
            {
                r = fscanf(fp, "%f %s\n", &temp, loc);  
                line++;
        
                if (r == 2)
                {
                    if(strcmp(argv[2], loc) == 0)
                    {
                        t_tot += temp;
                        found++;
                    }
                }
                else
                    printf ("Error, line %d in wrong format!\n\n", line);
            }
        
            printf ("The average temperature in %s is: %.1f\n\n", argv[2], t_tot);
        }
        
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-12-05
          • 1970-01-01
          • 2019-05-10
          • 1970-01-01
          • 2014-08-27
          • 2021-09-13
          • 1970-01-01
          相关资源
          最近更新 更多