我用C编写了这个简单的程序,因为我现在正在大学学习FILES。我带了一个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
当我运行我的程序时,它会返回第一个无限循环。为什么? 还有其他函数可以读取这些数据吗?
答案 0 :(得分:3)
这个有效(从@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;
}
答案 1 :(得分:2)
您的问题是您没有进行任何错误检查。 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",
答案 2 :(得分:2)
您需要在每次fscanf
来电后吞下行尾字符 - 例如在while块的开头:
{
fgetc(fp);
...
}
有关详细信息,请参阅此Microsoft KB article(该解释适用于任何C编译器)