gpt4 book ai didi

c - fread() 从二进制文件读取的意外行为

转载 作者:太空宇宙 更新时间:2023-11-03 23:22:48 25 4
gpt4 key购买 nike

这个程序基本上创建了一个包含所有信息的航类列表(由 ListaVoli.bin 中的 fread() 函数读取)。该列表主要由节点组成,每个节点包含一个航类。

#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;
}

代码编译正确,所以不要担心整个代码,关注 main() 函数和两个结构。关于 main() 函数中的 fread() 函数,我有两个问题:

  1. 为什么,如果我将 sizeof(int) 作为第二个参数,flight.destination 的值会被正确分配? char[3] 变量不应该大于 sizeof(int) 吗?
  2. 为什么,如果我将 sizeof(struct flight) 作为第二个参数(这将是最佳选择),我会得到段错误:11?

最佳答案

三个字符的数组是三个字节。 int 通常(至少在现代 32 位和 64 位平台上)是 4 个字节。它可以读取 sizeof(int),因为编译器添加了 padding

但是读取结构的“正确”(或至少通常)方法是将整个结构作为一个单元来读取,即在您的情况下使用 sizeof(volo):

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

如果因此而出现其他错误,则说明您做错了else

关于c - fread() 从二进制文件读取的意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34786706/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com