繁体   English   中英

使用 fscanf 时无限循环

[英]Infinite loop when using fscanf

我用 C 编写了这个简单的程序,因为我现在正在大学学习文件。 我拿了一个 txt 文件,里面列出了上一场比赛的结果,这样我的程序就会显示我想要的格式的数据。 这是我的代码:

/* Esercizio file Motogp */
#include <stdio.h>
#define SIZE 20

int main ()
{
    int pos, punt, num;
    float kmh;
    char nome[SIZE+1], cognome[SIZE+1], moto[SIZE+1];
    char naz[SIZE+1], nome_file[SIZE+1];

    FILE *fp;

    printf ("Inserisci il nome del file da aprire: ");
    gets (nome_file);

    fp = fopen (nome_file, "r");

    if (fopen == NULL)
        printf ("Errore nell' apertura del file %s\n", nome_file);
    else {

        while (fscanf (fp, "%d %d %d %s %s %s %s %.2f",
                &pos, &punt, &num, nome, cognome, naz, moto, &kmh) != EOF ) {

              printf ("Posizione di arrivo: %d\n", pos);
              printf ("Punteggio: %d\n", punt);
              printf ("Numero pilota: %d\n", num);
              printf ("Nome pilota: %s\n", nome);
              printf ("Cognome pilota: %s\n", cognome);
              printf ("Nazione: %s\n", naz);
              printf ("Moto: %s\n", moto);
              printf ("Media Kmh: %d\n\n", kmh);
        }
    }

    fclose(fp);

    return 0;
}

还有我的txt文件:

1   25  99  Jorge LORENZO    SPA    Yamaha  164.4   
2   20  26  Dani PEDROSA     SPA    Honda   164.1   
3   16  4   Andrea DOVIZIOSO ITA    Yamaha  163.8   
4   13  1   Casey STONER     AUS    Honda   163.8   
5   11  35  Cal CRUTCHLOW    GBR    Yamaha  163.6   
6   10  19  Alvaro BAUTISTA  SPA    Honda   163.5   
7   9   46  Valentino ROSSI  ITA    Ducati  163.3   
8   8   6   Stefan BRADL     GER    Honda   162.9   
9   7   69  Nicky HAYDEN     USA    Ducati  162.5   
10  6   11  Ben SPIES    USA    Yamaha  162.3   
11  5   8   Hector BARBERA   SPA    Ducati  162.1   
12  4   17  Karel ABRAHAM    CZE    Ducati  160.9   
13  3   41  Aleix ESPARGARO  SPA    ART 160.2   
14  2   51  Michele PIRRO    ITA    FTR 160.1   
15  1   14  Randy DE PUNIET  FRA    ART 160.0   
16  0   77  James ELLISON    GBR    ART 159.9   
17  0   54  Mattia PASINI    ITA    ART 159.4   
18  0   68  Yonny HERNANDEZ  COL    BQR 159.4   
19  0   9   Danilo PETRUCCI  ITA    Ioda    158.2   
20  0   22  Ivan SILVA   SPA    BQR 158.2

当我运行我的程序时,它返回第一个无限循环。 为什么? 是否有另一个函数来读取这些数据?

这个有效(从@Mahmoud Al-Qudsi 借来的;我不想要任何积分)

#include <stdio.h>
#define SIZE 20

int main (int argc, char **argv)
{
    int pos, punt, num;
    float kmh;
    char nome[SIZE+1], cognome[SIZE+1], moto[SIZE+1];
    char naz[SIZE+1];

    FILE *fp;

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

    if (!fp ) { printf ("Errore nell' apertura del file %s\n", argv[1]); return 0; }

        while (fscanf (fp, "%d %d %d %s %s %s %s %f\n",
                &pos, &punt, &num, nome, cognome, naz, moto, &kmh) == 8 ) {

              printf ("Posizione di arrivo: %d\n", pos);
              printf ("Punteggio: %d\n", punt);
              printf ("Numero pilota: %d\n", num);
              printf ("Nome pilota: %s\n", nome);
              printf ("Cognome pilota: %s\n", cognome);
              printf ("Nazione: %s\n", naz);
              printf ("Moto: %s\n", moto);
              printf ("Media Kmh: %f\n\n", kmh);
        }

    fclose(fp);

    return 0;
}

您的问题是您没有进行任何错误检查。 EOF 仅在文件末尾返回,但fscanf返回它匹配的参数数量,即使为 0。

在您的代码中, fscanf第一次匹配并读入变量,此后返回 0。 然后变量保留原始内容,并且您永远打印它。

如果您编译带有警告的代码,您会发现有多个问题:

test.c:23:51: warning: invalid conversion specifier '.'
      [-Wformat-invalid-specifier]
        while (fscanf (fp, "%d %d %d %s %s %s %s %.2f",
                                                ~~^

test.c:33:36: warning: conversion specifies type 'int' but the argument has type
      'double' [-Wformat]
              printf ("Media Kmh: %d\n\n", kmh);
                                  ~^       ~~~
                                  %f

如果您正在记录或检查fscanf的返回值,您会意识到您没有在每行的末尾检查\\n 您的 fprintf 应该(可能)看起来更像这样:

while (fscanf (fp, "%d %d %d %s %s %s %s %.2f\n",

您需要在每次fscanf调用之后吞下行尾字符——例如在 while 块的开头:

{
    fgetc(fp);
    ...
}

有关更多详细信息,请参阅此Microsoft KB 文章(该说明适用于任何 C 编译器)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM