web-dev-qa-db-ja.com

FscanfまたはFgets?行ごとにファイルを読み取る

数行のテキストを含むファイルを読み取るには、Cでプログラムを作成する必要があります。各行には、数値(%f)と文字列の2つの変数が含まれています。

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の方が良いですか?

私は学生なので、それを解決するための「アカデミック」な方法を教えてください:)

7
Lc0rE

いくつかのこと。

まず、fclose()を使用する必要があります。
次に、コードはファイルの各行をfscan()する必要があります。 while()ループの直前だけでなく、各whileループ内で、次の反復のためにfscan()を取得する必要があります。
第3に、平均気温を計算しているのではなく、見つかったすべての温度の合計を計算しているのです。最後のprintf()で「t_tot」を「(t_tot/found)」に変更して修正します。

最後に、なぜ出力が得られないのかわかりません。あなたの入力は「myprogramfile.txtMilano」のようなものですよね?私のために働きます。とにかく、ここにあなたの(編集された)コードがあります:

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

    }
}
11
dogglebones

コードがループ内でfscanfを呼び出す必要はありません。読み取りが一度行われると、ファイルが空の場合はプログラムがすぐに存在するか、無期限にループします。

fscanfの呼び出しをwhileループ内に移動する必要があります。コーディングの一般的な方法の1つは、次のように、ループヘッダー内に割り当てを配置することです。

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

whileループ内にfscanf行を配置する必要があります

    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);
     .............
  }
3
Riskhan

このようにコードを変更します... 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);
}

}
1
Ritesh Chandora