2012-06-23 161 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