2012-06-23 121 views
6

我必须写在C程序来读取包含文本的几行一个文件之后的文件中的行,每行包含两个变量:一个数字(%f)和一个串:Fscanf或Fgets?读取线

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

我是一个学生,所以,请给我一个“跑位”的方式来解决这个问题:)

回答

11

几件事情。

首先,你必须使用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); 

    } 
} 
+0

谢谢您的回答,我刚更正了我的代码。 – Lc0rE

2

您的代码像它应该不会调用fscanf在循环:读做一次,然后程序要么立即存在,如果文件是空的,或无限循环。

您应该在while循环内移动fscanf的呼叫。编码是将转让的循环水箱内,这样的一种典型方式:

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

谢谢你的回答。我只是意识到我的错误!如果我想用fgets而不是fscanf制作另一个解决方案,我怎么能做到这一点? – Lc0rE

+1

@l_core你需要改变一些东西:首先,你需要一个'fgets'的缓冲区;那么你可以用循环中的NULL检查来替换'EOF'的检查;最后,您需要手动解析缓冲区,找到第一个空格,将初始部分提供给'atof',并将其余部分复制到'strdup'中。 – dasblinkenlight

1

修改这样的代码...只是把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); 
} 

} 
3

你必须把的fscanf线while循环中

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

最后关闭文件

如果u使用与fgets变化如下

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

“1”留下什么? – Lc0rE

+1

1表示始终为真 – Riskhan

+1

请参阅我编辑的答案 – Riskhan