[英]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.