2
votes

This program basically creates a list of flights with all their infos (read by the fread() function from a ListaVoli.bin). The list is made up mainly by nodes and each node contains a flight.

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

#define FILE_NAME "/Users/Matt/Downloads/ListaVoli.bin"

struct flight {
    int flightCode;
    char destination[3];
    int scheduledDepHour;
    int scheduledDepMinute;
    int realDepHour;
    int realDepMinute;
    int passengers;
};

struct node {
    struct flight volo;
    struct node *next;
};

struct node *addToList(struct node *list, struct flight voloIn) {
    struct node *newNode;
    newNode = malloc(sizeof(struct node));

    if (newNode == NULL) {
        printf("Error: malloc failed\n");
        exit(EXIT_FAILURE);
    }

    newNode -> volo = voloIn;
    newNode -> next = list;
    return newNode;
}

void printList(struct node *list) {
    for (; list != NULL; list = list -> next) {
        printf("Code:%d\nDestination:%s\nDeparture:%d-%d\nReal:%d-%d\nPassengers:%d\n\n\n",
        list -> volo.flightCode,
        list -> volo.destination,
        list -> volo.scheduledDepHour,
        list -> volo.scheduledDepMinute,
        list -> volo.realDepHour,
        list -> volo.realDepMinute,
        list -> volo.passengers
        );
    }
}

void decolla(struct node *list, int flightCode, int realDepHour, int realDepMinute) {
    for (; list != NULL; list = list -> next) {
        if (flightCode == (list -> volo.flightCode)) { /*
            printf("Inserisci ora di partenza per il volo %d: ", flightCode);
            scanf("%d", &(list -> volo.realDepHour));
            printf("Inserisci minuto di partenza: ");
            scanf("%d", &(list -> volo.realDepMinute)); */
            list -> volo.realDepHour = realDepHour;
            list -> volo.realDepMinute = realDepMinute;
        }
    }
}

void delay(struct node *list) {
    for (; list != NULL; list = list -> next) {
        if ((list -> volo.realDepHour) - (list -> volo.scheduledDepHour) == 0) {
            if ((list -> volo.realDepMinute) - (list -> volo.scheduledDepMinute) > 5 && (list -> volo.realDepMinute) - (list -> volo.scheduledDepMinute) < 30) {
            printf("Il volo %d ha più di 5 minuti di ritardo\n", list -> volo.flightCode);
            continue;
            }
            if ((list -> volo.realDepMinute) - (list -> volo.scheduledDepMinute) > 30) {
                printf("Il volo %d ha più di 30 minuti di ritardo\n", list -> volo.flightCode);
                continue;
            }
        } else
            printf("Il volo %d ha più di 30 minuti di ritardo\n", list -> volo.flightCode);
    }
}

void passengersCount(struct node *list) {
    for (; list != NULL; list = list -> next) {
        if (list -> volo.passengers > 200) {
            printf("Il volo %d ha più di 200 passeggeri\n", list -> volo.flightCode);
            continue;
        }
    }
}

int main() {
    FILE *fp;
    struct node *first = NULL;
    struct flight volo;

    /* Apro il file e controllo che sia stato aperto correttamente */
    if ((fp = fopen(FILE_NAME, "rb")) == NULL) {
        printf("Can't open %s\n", FILE_NAME);
        exit(EXIT_FAILURE);
    }

    for (int i = 0; i < 4; i++) {
        fread(&volo, sizeof(int), 7, fp);
        first = addToList(first, volo);
    }

    decolla(first, 3497, 11, 30);
    decolla(first, 2193, 11, 53);
    decolla(first, 4284, 11, 07);
    decolla(first, 5536, 12, 26);
    printList(first);
    delay(first);
    passengersCount(first);

    /* Controllo che il file sia chiuso correttamente */
    if (fclose(fp) == EOF) {
        printf("File not closed properly!");
        exit(EXIT_FAILURE);
    }
    return 0;
}

The code compiles correctly so don't worry about the entire code, focus on the main() functions and the two structs. I have two questions regarding the fread() function in the main() function:

  1. Why, if I put sizeof(int) as the second parameter, the flight.destination value is assigned correctly? Shouldn't a char[3] variable be larger than sizeof(int)?
  2. Why, if I put sizeof(struct flight) as second parameter (which would be the best choice), I get segmentation fault:11?
1
If the rest of the code does not matter, you should not have posted it. Thats the idea of the the first part in minimal reproducible example.too honest for this site
You need the code to have a better understanding of the program. I have just said that the question is not about the entire program, but just the fread() function in the main() function.Matt
That's ok, but reading from a binary file is complex and a single bit can create big issues. As you said, int is 4 bytes, char[3] is 3 bytes, then the fread() should have read more bytes than it should right? Then why do I get the correct output (a string of 3 char)?Matt
There is no need to "understand the program". You have to tell what your specific problem is and provide the necessary code to reproduce. SO is a Q&A site, not a forum. See How to Ask.too honest for this site

1 Answers

2
votes

An array of three characters is three bytes. An int is usually (at least on modern 32 and 64 bit platforms) 4 bytes. It works to read sizeof(int) because the compiler adds padding.

But the "correct" (or at least usual) way to read the structure would be to read the whole structure as one single unit, i.e. using sizeof(volo) in your case:

fread(&volo, sizeof(volo), 1, fp);

If you get other errors because of it, you are doing something else wrong.