Dilara Anabolu
Dilara Anabolu

Reputation: 23

How can I read a txt file and place the information into struct in C?

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

Answers (2)

William Pursell
William Pursell

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

Armali
Armali

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

Related Questions