rendered paste body#include <stdio.h>#include <stdlib.h>#include <string.h>struct luggage_t{ int bIsRelevant; /* Set to 0 for superseded and filtered-out records */ char *sField[6]; /* Timestamp, ID, Flight, Departing, Arriving, Comment */ struct luggage_t *pNext; /* For a linked-list of luggage records */};void list_insert(struct luggage_t **ppList, struct luggage_t *pLuggage){ while(NULL != *ppList) { /* Luggage ID and departing airport identify a piece of luggage */ if(strcmp((**ppList).sField[1], pLuggage->sField[1]) == 0 && strcmp((**ppList).sField[3], pLuggage->sField[3]) == 0) (**ppList).bIsRelevant = 0; ppList = &(**ppList).pNext; } *ppList = pLuggage; pLuggage->bIsRelevant = 1; pLuggage->pNext = NULL;}int main(int argc, const char** argv){ struct luggage_t *pLuggage, *pLuggageList = NULL; int iField, iBufferSize = 16; /* 1) Load all luggage data */ for(;;) { char *sLine = malloc(iBufferSize), *sNextWord; if(!fgets(sLine, iBufferSize, stdin)) break; if(sLine[strlen(sLine) - 1] != '\n' && !feof(stdin)) { /* Buffer not large enough - double it until it is */ do { int iBufferUsed = iBufferSize - 1; /* -1 for '\0' */ iBufferSize = iBufferSize * 2; sLine = realloc(sLine, iBufferSize); fgets(sLine + iBufferUsed, iBufferSize - iBufferUsed, stdin); } while(sLine[strlen(sLine) - 1] != '\n' && !feof(stdin)); } pLuggage = malloc(sizeof(struct luggage_t)); /* Blank or incomplete lines are ignored */ pLuggage->sField[0] = strtok(sLine, " \r\n"); if(!pLuggage->sField[0]) continue; pLuggage->sField[1] = strtok(NULL, " \r\n"); if(!pLuggage->sField[1]) continue; pLuggage->sField[2] = strtok(NULL, " \r\n"); if(!pLuggage->sField[2]) continue; pLuggage->sField[3] = strtok(NULL, " \r\n"); if(!pLuggage->sField[3]) continue; pLuggage->sField[4] = strtok(NULL, " \r\n"); if(!pLuggage->sField[4]) continue; /* Previous fields are required, whereas comment is optional */ pLuggage->sField[5] = strtok(NULL, " \r\n"); if(pLuggage->sField[5]) { /* Finish the token splitting, and just reinsert the spaces */ while((sNextWord = strtok(NULL, " "))) sNextWord[-1] = ' '; } list_insert(&pLuggageList, pLuggage); } /* 2) Filter records using command line arguments */ for(pLuggage = pLuggageList; pLuggage; pLuggage = pLuggage->pNext) { for(iField = 1; iField < 5 && iField < argc; ++iField) { if(*argv[iField] == '-' && argv[iField][1] == '\0') /* Wildcard */ continue; if(strcmp(argv[iField], pLuggage->sField[iField]) != 0) pLuggage->bIsRelevant = 0; } } /* 3) Print all records (which weren't superseded or filtered-out) */ for(pLuggage = pLuggageList; pLuggage; pLuggage = pLuggage->pNext) { if(!pLuggage->bIsRelevant) continue; for(iField = 0; iField < 5; ++iField) printf("%s ", pLuggage->sField[iField]); if(pLuggage->sField[5]) fputs(pLuggage->sField[5], stdout); /* fgets kept the '\n' */ else putc('\n', stdout); putc('\r', stdout); } fputs("\n\r", stdout); /* 4) We could free all our memory now, but the O.S. will do it for us */ return 0;}