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