Error printing linked list using time functions

When printing a timestamp, the program crashes. I believe the error is in the void flightRec_PrflightRecData (flightRecRead * thisFlight) function, which is designed to do three things:

  • declare the execution time of the time structure, the flight time is in POSIX format.
  • Local time converts POSIX time to user-friendly time.
  • The fourth specifier prints the converted time using asctime, which prints it in the Www format Mmm dd hh: mm: ss yyyy.

The tb! = NULL error and shows other information indicating asctime.

What I did to troubleshoot:

  • Time Header Check
  • Verified pointers and addresses
  • Disabled deviation
  • Format specifier checked

Any help is appreciated.

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


typedef struct flightRec_struct { // declare a struct to match the format of the binary data
    char FlightNum[7];
    char OriginAirportCode[5];
    char DestAirportCode[5];
    int  timestamp;
} flightRec;

typedef struct flightRecRead_struct { // declare a struct to match the format of your linked list
    char FlightNum[7];
    char OriginAirportCode[5];
    char DestAirportCode[5];
    int  timestamp;
    struct flightRec* nextFlight_ptr;
} flightRecRead;



// Print dataVal
void flightRec_PrflightRecData(flightRecRead* thisFlight) {
    struct tm *flightTime;
    flightTime = localtime(&thisFlight->timestamp);
    printf("%s \t %s \t %s \t %s\n", thisFlight->FlightNum, thisFlight->OriginAirportCode,
        thisFlight->DestAirportCode, asctime(flightTime));
    return;
}

// Grab location pointed by nextFlight_ptr
flightRecRead* flightRec_GetNext(flightRecRead* thisFlight) {
    return thisFlight->nextFlight_ptr;
}

int main(void) {
    flightRec firstStruct;
    flightRecRead* headObj = NULL;
    flightRecRead* currObj = NULL;
    flightRecRead* tailObj = NULL;
    struct tm *flightTime;
    int i = 0;                               //loop index


    FILE* inFile = NULL;
    inFile = fopen("acars.bin", "rb");
    if (inFile == NULL) {
        printf("Could not open file acars.bin.\n");
        return -1;
    }

    if (!feof(inFile)) {
        fread(&firstStruct, sizeof(flightRec), 1, inFile); // 2. read the file into that struct

        headObj = (flightRecRead*)malloc(sizeof(flightRecRead)); // 3. make head point to that struct
        strcpy(headObj->FlightNum, firstStruct.FlightNum);
        strcpy(headObj->OriginAirportCode, firstStruct.OriginAirportCode);
        strcpy(headObj->DestAirportCode, firstStruct.DestAirportCode);
        headObj->timestamp = firstStruct.timestamp;

        tailObj = (flightRecRead*)malloc(sizeof(flightRecRead));  // 4. make tail point to that struct
        strcpy(tailObj->FlightNum, firstStruct.FlightNum);
        strcpy(tailObj->OriginAirportCode, firstStruct.OriginAirportCode);
        strcpy(tailObj->DestAirportCode, firstStruct.DestAirportCode);
        tailObj->timestamp = firstStruct.timestamp;
        headObj->nextFlight_ptr = tailObj;
        tailObj->nextFlight_ptr = NULL;
    }

    while (!feof(inFile)) {                       // 5. while not end-of-file on the acars file:
        fread(&firstStruct, sizeof(flightRec), 1, inFile); // 6. malloc a new struct
        currObj = (flightRecRead*)malloc(sizeof(flightRecRead));
        strcpy(currObj->FlightNum, firstStruct.FlightNum);
        strcpy(currObj->OriginAirportCode, firstStruct.OriginAirportCode);
        strcpy(currObj->DestAirportCode, firstStruct.DestAirportCode);
        currObj->timestamp = firstStruct.timestamp;
        currObj->nextFlight_ptr = NULL;

        tailObj->nextFlight_ptr = currObj;
        tailObj = currObj;
    }


    currObj = headObj;                           // Print the list
    printf("FlightNum \t OriginAirportCode \t DestAirportCode \t Time \t \n");
    while (currObj != NULL) {
        flightRec_PrflightRecData(currObj);
        currObj = flightRec_GetNext(currObj);
    }

    system("pause"); //return 0;
}

      

-1


source to share


1 answer


When I compile your code on a 64-bit Mac with GCC 5.1.0 it gives me several errors. Some of them, however, are a consequence of the very strict compilation options I use:

$ gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
>     -Wold-style-definition -Werror timecrash.c -o timecrash
timecrash.c:25:6: error: no previous prototype for ‘flightRec_PrflightRecData’ [-Werror=missing-prototypes]
 void flightRec_PrflightRecData(flightRecRead* thisFlight) {
      ^
timecrash.c: In function ‘flightRec_PrflightRecData’:
timecrash.c:27:28: error: passing argument 1 of ‘localtime’ from incompatible pointer type [-Werror=incompatible-pointer-types]
     flightTime = localtime(&thisFlight->timestamp);
                            ^
In file included from timecrash.c:4:0:
/usr/include/time.h:112:12: note: expected ‘const time_t * {aka const long int *}’ but argument is of type ‘int *’
 struct tm *localtime(const time_t *);
            ^
timecrash.c: At top level:
timecrash.c:34:16: error: no previous prototype for ‘flightRec_GetNext’ [-Werror=missing-prototypes]
 flightRecRead* flightRec_GetNext(flightRecRead* thisFlight) {
                ^
timecrash.c: In function ‘flightRec_GetNext’:
timecrash.c:35:12: error: return from incompatible pointer type [-Werror=incompatible-pointer-types]
     return thisFlight->nextFlight_ptr;
            ^
timecrash.c: In function ‘main’:
timecrash.c:68:33: error: assignment from incompatible pointer type [-Werror=incompatible-pointer-types]
         headObj->nextFlight_ptr = tailObj;
                                 ^
timecrash.c:81:33: error: assignment from incompatible pointer type [-Werror=incompatible-pointer-types]
         tailObj->nextFlight_ptr = currObj;
                                 ^
timecrash.c:44:9: error: unused variable ‘i’ [-Werror=unused-variable]
     int i = 0;                               //loop index
         ^
timecrash.c:43:16: error: unused variable ‘flightTime’ [-Werror=unused-variable]
     struct tm *flightTime;
                ^
cc1: all warnings being treated as errors
$

      

"Unused variables" and "no previous prototypes" errors (would be warnings, except what I used -Werror

to force all warnings to be treated as errors).

But misuse int

as a surrogate for time_t

can be a problem for you too. This can be a problem when compiling for a 32-bit platform.

Other warnings about an incompatible pointer are troubling as well. In fact, your second definition of structure is wrong. You have:

typedef struct flightRec_struct {
    char FlightNum[7];
    char OriginAirportCode[5];
    char DestAirportCode[5];
    int  timestamp;
} flightRec;

typedef struct flightRecRead_struct {
    char FlightNum[7];
    char OriginAirportCode[5];
    char DestAirportCode[5];
    int  timestamp;
    struct flightRec* nextFlight_ptr;
} flightRecRead;

      

struct flightRec *

- pointer to incomplete type. It is not struct flightRec_struct

, nor a flightRec

(and not struct flightRecRead_struct

a flightRecRead

). In fact, you need it to be either struct flightRecRead_struct *

, or you need to provide a type and use flightRecRead *

:

typedef struct flightRecRead_struct flightRecRead;
struct flightRecRead_struct {
    char FlightNum[7];
    char OriginAirportCode[5];
    char DestAirportCode[5];
    int  timestamp;
    flightRecRead *nextFlight_ptr;
};

      

You can simplify the job part of your code by using:

struct flightRecRead_struct
{
    flightRec      flight;
    flightRecRead *nextFlight_ptr;
};

      

Then you can assign the entire structure flightRec

on one line, instead of writing multiple operations strcpy()

, etc.



Against this, if you need to use time_t

and it is not the same size int

as and the binary format is externally corrected, then you might need to do a bulk copy.

You must find out why it is while (!feof(file))

always wrong
.


Semi-fixed code: timecrash.c

This code works more or less.

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

typedef struct flightRec_struct
{
    char FlightNum[7];
    char OriginAirportCode[5];
    char DestAirportCode[5];
    time_t timestamp;
} flightRec;

typedef struct flightRecRead_struct flightRecRead;
struct flightRecRead_struct
{
    char FlightNum[7];
    char OriginAirportCode[5];
    char DestAirportCode[5];
    time_t timestamp;
    flightRecRead *nextFlight_ptr;
};

static
void flightRec_PrflightRecData(flightRecRead *thisFlight)
{
    struct tm *flightTime = localtime(&thisFlight->timestamp);
    printf("timestamp = 0x%.8lX\n", (long)thisFlight->timestamp);
    assert(flightTime != 0);
    printf("%s \t %s \t %s \t %s\n", thisFlight->FlightNum, thisFlight->OriginAirportCode,
           thisFlight->DestAirportCode, asctime(flightTime));
}

static
flightRecRead *flightRec_GetNext(flightRecRead *thisFlight)
{
    return thisFlight->nextFlight_ptr;
}

int main(void)
{
    flightRec firstStruct;
    flightRecRead *headObj = NULL;
    flightRecRead *currObj = NULL;
    flightRecRead *tailObj = NULL;
    const char filename[] = "acars.bin";
    int recnum = 0;
    FILE *inFile = fopen(filename, "rb");

    if (inFile == NULL)
    {
        fprintf(stderr, "Could not open file %s.\n", filename);
        return -1;
    }

    if (fread(&firstStruct, sizeof(flightRec), 1, inFile) == 1)
    {
        printf("Record %d\n", ++recnum);
        headObj = (flightRecRead *)malloc(sizeof(flightRecRead));
        strcpy(headObj->FlightNum, firstStruct.FlightNum);
        strcpy(headObj->OriginAirportCode, firstStruct.OriginAirportCode);
        strcpy(headObj->DestAirportCode, firstStruct.DestAirportCode);
        headObj->timestamp = firstStruct.timestamp;
        flightRec_PrflightRecData(headObj);

        tailObj = (flightRecRead *)malloc(sizeof(flightRecRead));
        strcpy(tailObj->FlightNum, firstStruct.FlightNum);
        strcpy(tailObj->OriginAirportCode, firstStruct.OriginAirportCode);
        strcpy(tailObj->DestAirportCode, firstStruct.DestAirportCode);
        tailObj->timestamp = firstStruct.timestamp;
        flightRec_PrflightRecData(tailObj);

        headObj->nextFlight_ptr = tailObj;
        tailObj->nextFlight_ptr = NULL;
    }

    while (fread(&firstStruct, sizeof(flightRec), 1, inFile) == 1)
    {
        printf("Record %d\n", ++recnum);
        currObj = (flightRecRead *)malloc(sizeof(flightRecRead));
        strcpy(currObj->FlightNum, firstStruct.FlightNum);
        strcpy(currObj->OriginAirportCode, firstStruct.OriginAirportCode);
        strcpy(currObj->DestAirportCode, firstStruct.DestAirportCode);
        currObj->timestamp = firstStruct.timestamp;
        currObj->nextFlight_ptr = NULL;
        flightRec_PrflightRecData(currObj);

        tailObj->nextFlight_ptr = currObj;
        tailObj = currObj;
    }
    printf("Finished reading\n");

    currObj = headObj;
    printf("FlightNum \t OriginAirportCode \t DestAirportCode \t Time \t \n");
    recnum = 0;
    while (currObj != NULL)
    {
        printf("Record %d\n", ++recnum);
        flightRec_PrflightRecData(currObj);
        currObj = flightRec_GetNext(currObj);
    }

    fclose(inFile);

    system("pause");
}

      

Run example

The data generation is assumed to time_t

be a 64-bit type aligned on an 8-byte boundary (7 zero padding bytes before it) and formatted in little-endian (like on Intel).

$ printf "BA7231\0LHR\0\0LGW\0\0\0\0\0\0\0\0\0\xA2\x93\x84\x75\0\0\0\0" > acars.bin
$ printf "UA9240\0LAX\0\0AMS\0\0\0\0\0\0\0\0\0\x72\x93\x84\x75\0\0\0\0" >> acars.bin
$ odx acars.bin
0x0000: 42 41 37 32 33 31 00 4C 48 52 00 00 4C 47 57 00   BA7231.LHR..LGW.
0x0010: 00 00 00 00 00 00 00 00 A2 93 84 75 00 00 00 00   ...........u....
0x0020: 55 41 39 32 34 30 00 4C 41 58 00 00 41 4D 53 00   UA9240.LAX..AMS.
0x0030: 00 00 00 00 00 00 00 00 72 93 84 75 00 00 00 00   ........r..u....
0x0040:
$ ./timecrash
Record 1
timestamp = 0x758493A2
BA7231   LHR     LGW     Wed Jun 23 10:00:18 2032

timestamp = 0x758493A2
BA7231   LHR     LGW     Wed Jun 23 10:00:18 2032

Record 2
timestamp = 0x75849372
UA9240   LAX     AMS     Wed Jun 23 09:59:30 2032

Finished reading
FlightNum    OriginAirportCode   DestAirportCode     Time    
Record 1
timestamp = 0x758493A2
BA7231   LHR     LGW     Wed Jun 23 10:00:18 2032

Record 2
timestamp = 0x758493A2
BA7231   LHR     LGW     Wed Jun 23 10:00:18 2032

Record 3
timestamp = 0x75849372
UA9240   LAX     AMS     Wed Jun 23 09:59:30 2032

^C
$

      

The interrupt was necessary because mine pause

on Mac OS X doesn't end until interrupted (or otherwise sent a signal).

+1


source







All Articles