Reputation: 23
I'm trying to read txt files and place the information into structs for a C class project. My code doesn't seem to read the file and put the info into struct. I read many blog posts but I can't find or correct my mistakes.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct flightData {
char airline[9];
int flightCode;
char departureAirport[3];
char destinationAirport[3];
int passengerCapacity;
int depTimeHour;
int depTimeMin;
int arvTimeHour;
int arvTimeMin;
};
int main(){
FILE *flightFile;
flightFile = fopen("flights.txt","r");
int flightCount=0;
struct flightData input[10];
if (flightFile == NULL)
{
fprintf(stderr, "\nError opening file\n");
exit (1);
}
while (fscanf(flightFile,"%s %d %s %s %d %d:%d %d:%d", input[flightCount].airline,&input[flightCount].flightCode,input[flightCount].departureAirport,input[flightCount].destinationAirport
,&input[flightCount].passengerCapacity,&input[flightCount].depTimeHour,&input[flightCount].depTimeMin,&input[flightCount].arvTimeHour,&input[flightCount].arvTimeMin)!= EOF){
flightCount++;
printf ("%s\n",input[flightCount].airline);
}
fclose(flightFile);
return 0;
}
And here is the .txt file
THY 12345 IST DUD 10 20:05 16:10
LUFTHANSA 23356 IST MUC 10 11:55 12:40
PEGASUS 34567 SAW MUC 10 12:20 17:00
PEGASUS 45678 SAW XSP 10 01:55 17:20
EMIRATES 67890 ADB HKG 10 19:45 15:50
THY 78901 SAW IST 10 07:20 08:25
From this code I'm getting this result:
X����
P+�
Upvotes: 2
Views: 107
Reputation: 212248
You must never use "%s"
in scanf
. It is no better than gets
. To use %s
safely in a scanf you must use a maximum field width in the conversion specifier that is one less than the size of the buffer. scanf
will read no more than the number of characters specified, and will write the characters read plus a null terminator. There are a few other (mostly trivial) issues in your code. Try something like:
int
main(int argc, char **argv)
{
const char *path = argc > 1 ? argv[1] : "flights.txt";
FILE *flightFile = fopen(path,"r");
int flightCount=0;
struct flightData input[10], *t = input;
if( flightFile == NULL ) {
perror(path);
return EXIT_FAILURE;
}
char fmt[128];
snprintf(fmt, sizeof fmt, "%%%zus %%d %%%zus %%%zus %%d %%d:%%d %%d:%%d",
sizeof t->airline - 1, sizeof t->departureAirport - 1,
sizeof t->destinationAirport - 1);
while( fscanf(flightFile, fmt, t->airline, &t->flightCode,
t->departureAirport, t->destinationAirport,
&t->passengerCapacity, &t->depTimeHour, &t->depTimeMin,
&t->arvTimeHour, &t->arvTimeMin) == 9 )
{
t += 1;
}
fclose(flightFile);
flightCount = t - input;
for( int i = 0; i < flightCount; i++ ){
printf("%s\n", input[i].airline);
}
return 0;
}
Note that you may want to add some additional diagnostics. Given your current struct definition (in which the strings are too small), this example will enter the body of the while loop zero times and set flightCount
to zero, since scanf
will not be able to read the first line of input. Handling that is left as an exercise for the reader.
Upvotes: 1
Reputation: 19375
The most severe error apart from the ones mentioned in the question comments is the lines
flightCount++;
printf ("%s\n",input[flightCount].airline);
where the index flightCount
is incremented before the input
array is accessed, hence an uninitialized value is retrieved. Swap those two lines, do what the above comments recommend, and it will look much better.
Upvotes: 0