3

I am having trouble with this code, and I'm not sure what I'm doing wrong

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

typedef struct flight_struct{
    char flightNum[7];
    char originAirport[5];
    char destAirport [5];
    int timestamp;
    struct flight_struct *next;
} flightRec;

int main(){
struct flight_struct *head; // unchanging first node.
struct flight_struct *tail; //the conductor.
struct flight_struct *p; // first new struct
FILE* binFile = fopen("acars.bin","r");
FILE* DataOut;

    p =(struct flight_struct*) malloc(sizeof(*p) + 1); //malloc the first struct\

    fread(p,sizeof(*p),1,binFile);  //read the file into it.

    head = p; //make head point to that struct
    tail = p; //make tail point to that struct

//  fclose(binFile);

    while (feof(binFile) == 0){
    flight_struct *temp = (struct flight_struct*) malloc(1*sizeof(*temp) + 1); //malloc a new struct
    fread(temp,sizeof(*temp),1,binFile); //read the next struct from acars.bin into the structure you malloc'ed
    temp -> next = NULL; // add that struct to your linked list using the next memeber of the struct
    tail -> next = temp; // set tail to point to the element you just added
    tail = tail -> next;
    } //while not eof on acars file

    tail = head;

    while(tail -> next != 0 ){  
        int t;
        t = tail -> timestamp;
        time_t tim = t;
        printf("%s, %s, %s, %s\n\n",tail -> flightNum,tail -> originAirport,tail -> destAirport,asctime(gmtime(&tim)));
        tail = tail -> next;
    } //starting at head traverse the list printing the leemnts of each strucure
}

Now, what I am getting as a result is What i'm getting

What I should be getting is What I should be getting

Honestly I don't know what I'm doing wrong, and help would be nice. That being said, I can't use arrays so a linked list is the only way to do it.

9
  • 2
    Your flight_struct struct is probably being padded out in memory by the compiler in a way that doesn't match the format of your file. You need to read each field one at a time and copy it into the struct instead of reading the whole struct at once. Commented Apr 30, 2015 at 2:41
  • Do you have any idea how to do that from a .txt or .bin file? Commented Apr 30, 2015 at 2:43
  • I agree with @samgak - never read and write directly into a struct because your code and data-files won't be portable between machines. Commented Apr 30, 2015 at 2:44
  • Any hints on how to start doing that? I have been trying to work with this code for about two days and I am completely out of ideas... Commented Apr 30, 2015 at 2:46
  • 2
    Having struct flight_struct *next; in the structure you read from forces that amount of data to be read from the file into the pointer (which you then overwrite). I seriously doubt that "next" is part of the information in the datafile, so by reading it that way you are messing up the alignment of how you read the file, not to mention the issue with internal structure padding doing the same thing. Use separate freads to read each element, checking the return value (to make sure 1 thing was read each time) and the !feof() does not work the way you think it does. Commented Apr 30, 2015 at 3:37

3 Answers 3

2

You shouldn't have a pointers in your file.

Because order of elements in file automagically sets the order in your list (obviously). I doubt that file contains a pointers to sctructure and it's okay (pointers can be different in different architectures, ta-da).

What to do?

Given data structure:

struct flight_struct {
  char flightNum[7];
  char originAirport[5];
  char destAirport [5];
  int timestamp;
}

Implement the list struct:

struct list {
  flight_struct* data;
  list* next;
  list* prev; //if you want bi-directional list
}

And load from file just the data structure into list struct.

Writing pointers into binary file is wrong and may cause a lot of problems. Did you create file with objects by yourself or it is from other source?

Sign up to request clarification or add additional context in comments.

Comments

1

Here is a solution that seems to work:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

typedef struct flight_struct{
    char flightNum[7],originAirport[5], destAirport [5];
    size_t timestamp;
    struct flight_struct *next;
} flightRec;


int readFlight(FILE* file, flightRec *fr);

int main() {
    FILE *f = fopen("input.txt", "r");
    if (f != NULL) {
        while (feof(f) == 0) {
            flightRec fr;
            if (readFlight(f, &fr) == 0) {

                printf("%s, %s, %s, %s\n", fr.flightNum, fr.originAirport,
                        fr.destAirport, ctime((time_t*)(&fr.timestamp)));
            }
            else {
                fprintf(stderr, "Couldn't read the file information");
                break;
            }
        }
    }

    fclose(f);
    return 0;
}

int readFlight(FILE* file, flightRec *fr) {
    struct tm tstr;
    char *buffer = NULL, time[40];
    size_t len = 0;
    getline(&buffer, &len, file);

    int v = sscanf(buffer, "%6s%*[^ ]%4s%*[^ ]%4s%*[^a-zA-Z]%[^\n\r]", fr->flightNum, fr->originAirport,
                                                fr->destAirport, time);
    free(buffer);
    if (v == 4) {
        strptime(time, "%a %b %d %T %Y", &tstr);
        tstr.tm_isdst = -1;
        fr->timestamp = (size_t)mktime(&tstr);
        return 0;
    }
    return -1;
}

Input file:

XE4608, KIAH, KRSW, Mon Oct 21 15:25:00 2013
XE4232, KSDH, KASW, Sat Mar 29 16:38:00 2014
XE3453, MASH, KRSW, Wed Jan 01 19:10:00 2014
ZF4608, SAAH, KRSW, Tue Mar 25 18:49:00 2014

Output:

XE4608, KIAH, KRSW, Mon Oct 21 15:25:00 2013

XE4232, KSDH, KASW, Sat Mar 29 16:38:00 2014

XE3453, MASH, KRSW, Wed Jan  1 19:10:00 2014

ZF4608, SAAH, KRSW, Tue Mar 25 18:49:00 2014

Made a change to the struct so that timestamp is size_t type rather than int.

Comments

0

Are you sure that the file contains the full struct? Even with the space for the pointers?

And isn't your linking off? Shouldn't this be:

temp-> next = null;
if ( tail == null )
{
    head = temp;
    tail = temp;
}
else
{ 
   tail-> next = temp;
   tail = temp;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.