c - Linked List Print Error Using Time Functions -
the program crashes when printing timestamp. believe error located in function void flightrec_prflightrecdata(flightrecread* thisflight) designed 3 things:
- declare time struct flighttime, flighttime in posix format.
- localtime converts posix time human-readable time.
- the fourth specifier prints converted time using asctime prints in www mmm dd hh:mm:ss yyyy format.
the error tb != null , shows other information specifying asctime.
what have done troubleshoot:
- check time header
- checked pointers , addresses
- turned deprecation off
- checked format specifier
any assistance appreciated.
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> typedef struct flightrec_struct { // declare struct match format of binary data char flightnum[7]; char originairportcode[5]; char destairportcode[5]; int timestamp; } flightrec; typedef struct flightrecread_struct { // declare struct match format of 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 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 = 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 file struct headobj = (flightrecread*)malloc(sizeof(flightrecread)); // 3. make head point 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 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 acars file: fread(&firststruct, sizeof(flightrec), 1, infile); // 6. malloc 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 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; }
when compile code on 64-bit mac gcc 5.1.0, gives me number of errors. of them, though, consequences of stringent compilation options 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 ‘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’ incompatible pointer type [-werror=incompatible-pointer-types] flighttime = localtime(&thisflight->timestamp); ^ in file included timecrash.c:4:0: /usr/include/time.h:112:12: note: expected ‘const time_t * {aka const long int *}’ argument of type ‘int *’ struct tm *localtime(const time_t *); ^ timecrash.c: @ top level: timecrash.c:34:16: error: no previous prototype ‘flightrec_getnext’ [-werror=missing-prototypes] flightrecread* flightrec_getnext(flightrecread* thisflight) { ^ timecrash.c: in function ‘flightrec_getnext’: timecrash.c:35:12: error: return incompatible pointer type [-werror=incompatible-pointer-types] return thisflight->nextflight_ptr; ^ timecrash.c: in function ‘main’: timecrash.c:68:33: error: assignment incompatible pointer type [-werror=incompatible-pointer-types] headobj->nextflight_ptr = tailobj; ^ timecrash.c:81:33: error: assignment incompatible pointer type [-werror=incompatible-pointer-types] tailobj->nextflight_ptr = currobj; ^ timecrash.c:44:9: error: unused variable ‘i’ [-werror=unused-variable] int = 0; //loop index ^ timecrash.c:43:16: error: unused variable ‘flighttime’ [-werror=unused-variable] struct tm *flighttime; ^ cc1: warnings being treated errors $
the 'unused variables' , 'no previous prototype' errors (would warnings except used -werror
force warnings treated errors).
but misuse of int
surrogate time_t
problem too. may less of issue if compile 32-bit platform.
the other 'incompatible pointer type' warnings worrying, too. in fact, second structure definition incorrect. 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;
the struct flightrec *
pointer incomplete type. not struct flightrec_struct
nor flightrec
(nor struct flightrecread_struct
nor flightrecread
). in fact, need either struct flightrecread_struct *
or need predeclare type , 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 simplify assignment part of code using:
struct flightrecread_struct { flightrec flight; flightrecread *nextflight_ptr; };
you assign entire flightrec
structure in single line, rather having write out multiple strcpy()
operations, etc.
against this, if need use time_t
, not same size int
, binary format fixed externally, may need member-wise copying after all.
you should learn why while (!feof(file))
wrong.
semi-fixed code: timecrash.c
this code more or less works me.
#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"); }
sample run
the data generation assumes time_t
64-bit type aligned on 8-byte boundary (7 null padding bytes before it), , formatted in little-endian (as 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 necessary because pause
on mac os x doesn't terminate until interrupted (or otherwise sent signal).
Comments
Post a Comment