gpt4 book ai didi

c - append 到 C 中的文件,读取到结构数组

转载 作者:太空宇宙 更新时间:2023-11-04 02:15:29 25 4
gpt4 key购买 nike

该程序要求用户在必要时输入一些记录(结构)并将它们 append 到现有文件或如果没有则创建一个新文件,然后列出文件的内容。

#include <stdio.h>
#include <string.h>
#define N 25

int main() {

struct studrec {
char name[20], surname[20], sex, date[12];
} students[N];
int i, count = 0;
char another;

FILE *fileptr;

for (i = 0; i < 10; i++) {
puts("Press y to continue without adding new records");
another = getchar();
if (another == 'y' || another == 'Y') break;
while ((another = getchar()) != '\n' && another != EOF);
puts("Input info");

puts("Name: ");
if (fgets(students[i].name, sizeof(students[i].name), stdin) == NULL) return 1;
students[i].name[strlen(students[i].name)-1] = '\0';

puts("Surname: ");
if (fgets(students[i].surname, sizeof(students[i].surname), stdin) == NULL) return 1;
students[i].surname[strlen(students[i].surname)-1] = '\0';

puts("Sex (m/f): ");
students[i].sex = getchar();
while ((another = getchar()) != '\n' && another != EOF);

puts("Date (dd.mm.yyyy): ");
if (fgets(students[i].date, sizeof(students[i].date), stdin) == NULL) return 1;
students[i].date[strlen(students[i].date)-1] = '\0';
while ((another = getchar()) != '\n' && another != EOF);
}
count = i;

fileptr = fopen("students.txt", "a+");
for (i = 0; i < count; i++) fwrite(&students, sizeof(students), 1, fileptr);

rewind(fileptr);
for (i = 0; (another = fgetc(fileptr)) != EOF && i < N; i++) {
fseek(fileptr, -1, SEEK_CUR);
fread(&students, sizeof(students), 1, fileptr);
}
fclose(fileptr);

count = i;
for (i = 0; i < count; i++) printf("%20s%20s%4c%15s\n", students[i].name, students[i].surname, students[i].sex, students[i].date);

return 0;
}

写入新文件时一切正常。输出:

...input procedure...
Press y to continue without adding new records
y
Liam James m 12.03.1987
Abbey Trueman f 23.07.1943
Hugo Brown m 13.05.1947

但是如果我再次运行它并尝试将另一条记录 append 到现有文件,程序将失败:

...input procedure...
Press y to continue without adding new records
y
Nadia Rachmonoff f 12.07.1934
O|u
�u � u
� E�u

似乎新记录放在了students[0]中,其他所有元素都被删除了。我究竟做错了什么?也许 &students 指针有问题。我尝试使用 &students[i] 但它在第一次迭代后返回“段错误”。据我了解, &students 地址在每次 fread/fwrite 后“自动”递增到下一个元素。否则程序将无法在第一次运行时正常运行。

最佳答案

您在处理数组的方式上遇到了一些问题。首先,这一行:

for (i = 0; i < count; i++) fwrite(&students, sizeof(students), 1, fileptr);

你在这里做的是运行一个循环,每输入一条记录一次,每次都将包含 25 个项目的整个数组写入文件。所以如果输入了 3 条记录,你写的是 75,其中大部分是垃圾或多余的。您在这里可能想要的更像这样:

for (i = 0; i < count; i++)
fwrite(&students[i], sizeof(students[i]), 1, fileptr);

...其中大小是数组(单个记录)的一个元素的大小,地址是您当前正在写入的记录的地址,而不是整个数组。

你在后面读取数据的时候也有类似的问题,除此之外:

rewind(fileptr);
for (i = 0; (another = fgetc(fileptr)) != EOF && i < N; i++) {
fseek(fileptr, -1, SEEK_CUR);
fread(&students, sizeof(students), 1, fileptr);
}

首先,fread(&students, sizeof(students), 1, fileptr); 应该像之前的 fwrite() 一样更改为 fread (&students[i], sizeof(students[i]), 1, fileptr);.原因是一样的:你在一个循环中一次读取一条记录,所以你需要读入那个项目,而不仅仅是每次到数组的开头,以及数据量您读取的应该是那条记录 的大小,而不是整个数组的大小。

其次,虽然修复上面的问题应该可以让它工作,但您可以轻松更改循环,这样您就不需要读取循环表达式中的单个 char 来检查 EOF。您应该通过检查循环中 fread() 的返回来真正检查这一点。像这样的东西:

rewind(fileptr);
for (i = 0; i < N; i++) {
if (fread(&students[i], sizeof(students[i]), 1, fileptr) != 1)
break;
}

或者更好的是,只读取 N 项而不用循环,并使用返回值告诉您读取了多少:

rewind(fileptr);
i = fread(students, sizeof(students[0]), N, fileptr);

关于c - append 到 C 中的文件,读取到结构数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8371014/

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