I wrote this simple program in C, because I'm studying FILES right now at University. I take a txt file with a list of the results of the last race so my program will show the data formatted as I want. Here's my code:
/* 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;
}
and there's my txt file:
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
When I run my program, it return me an infinite loop of the first one. Why? Is there another function to read those data?
This one works (borrowed from @Mahmoud Al-Qudsi; I don't want any points for this)
#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;
}
Your problem is that you are not doing any error checking. EOF is only returned at the end of file, but fscanf
returns the number of arguments it matched otherwise, even if 0.
In your code, fscanf
matches and reads into the variables just the first time, returning 0 thereafter. The variables then retain the original content, and you print it forever anon.
If you compiled your code with warnings, you'd see you have multiple issues:
test.c:23:51: warning: invalid conversion specifier '.'
[-Wformat-invalid-specifier]
while (fscanf (fp, "%d %d %d %s %s %s %s %.2f",
~~^
and
test.c:33:36: warning: conversion specifies type 'int' but the argument has type
'double' [-Wformat]
printf ("Media Kmh: %d\n\n", kmh);
~^ ~~~
%f
And if you were logging or checking the return value of fscanf
, you'd realize that you're not checking for \\n
at the end of each line. Your fprintf should (possibly) look more like this:
while (fscanf (fp, "%d %d %d %s %s %s %s %.2f\n",
You need to swallow the end-of-line character after every fscanf
call -- eg at the beginning of the while block:
{
fgetc(fp);
...
}
see this Microsoft KB article for more details (the explanation applies to any C compiler)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.