附加到C中的文件,读取结构的数组

附加到C中的文件,读取结构的数组,c,append,fwrite,fread,C,Append,Fwrite,Fread,如果需要,程序会要求用户输入一些记录(结构),并将它们附加到现有文件中,如果没有,则创建一个新文件,然后列出文件的内容 #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 a

如果需要,程序会要求用户输入一些记录(结构),并将它们附加到现有文件中,如果没有,则创建一个新文件,然后列出文件的内容

#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
               Nadia          Rachmonoff   f     12.07.1934
                                    O|u                  
                  �u                       �              u
                                           �           E�u
似乎新记录被放入了students[0],而所有其他元素都被删除了。
我做错了什么?可能是&students指针有问题。我尝试了&students[I],但在第一次迭代后它返回了“分段错误”。据我所知,&students地址在每次fread/fwrite之后“自动”递增到下一个元素。如果不是这样,程序在第一次运行时将无法正常工作。

以下写入整个25元素数组的次数:

for (i = 0; i < count; i++) fwrite(&students, sizeof(students), 1, fileptr);
for(i=0;i
有两种方法可以解决此问题:

  • 计算
    count
    元素占用的正确大小,并通过单个
    fwrite
    调用将其写出
  • 使用循环每次写出一个条目

  • 尝试回读元素的循环也是如此:每次迭代都读取整个25元素数组,如果您编写的代码不正确,请重试

       fwrite(students, sizeof*students, i, fileptr);
    
       rewind(fileptr);
       for (i = 0; i < N && fread(&students[i], sizeof*students, 1, fileptr); i++);
    
    fwrite(学生,大小*students,i,fileptr);
    倒带(文件服务器);
    对于(i=0;i
    您在如何处理阵列方面遇到了一些问题。首先,这一行:

    for (i = 0; i < count; i++) fwrite(&students, sizeof(students), 1, fileptr);
    
    或者更好的方法是,只需读取没有循环的
    N
    项,然后使用返回值告诉您读取了多少:

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

    为什么要给学生写文件计数时间?@RomanB:运行代码并查看输出文件后很容易。+1只是好奇而已。写这么长的答案的动机是什么?@RomanB。只是为了更清楚。海报所犯的各种错误可能只有那些难以理解细节的人才会犯,因此简短的回答可能是不够的。我宁愿解释得太多也不愿解释得不够;额外的细节可以忽略,但缺少细节只会使答案毫无帮助。@RomanB.-为什么不写一个冗长详细的答案呢?我完全不理解这种情绪。Dmitri登录到Stack Overflow以询问和回答问题。提供简洁的答案似乎比提供详细的答案更有意义!KevinVermeer嗯,这只是他和我之间的一次讨论。但如果你也加入了,我也可以问你同样的问题。我不明白是什么促使高度专业的开发人员编写这样的答案,甚至阅读这段代码。但你不是那个人。所以你不是该问的人。@KevinVermeer抱歉,我之前的评论中漏掉了@。
    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);
    }
    
    rewind(fileptr);
    for (i = 0; i < N; i++) {
      if (fread(&students[i], sizeof(students[i]), 1, fileptr) != 1)
        break;
    }
    
    rewind(fileptr);
    i = fread(students, sizeof(students[0]), N, fileptr);