如何使用write / fread在/从结构数组中写入/读取数据?

时间:2014-03-02 09:32:31

标签: c arrays structure fwrite fread

我花了很多时间试图找到一个解决方案,如何在文件中写入和读取结构并完全卡住。

代码应该非常简单,但我认为我错过了关于fwrite / fread的非常重要的详细信息。我认为写作是有效的,但我不完全确定。一旦我尝试读入数组,我就会在k=1上获得分段错误错误。

如果有人能指导我进一步向前迈进,我会感到高兴。

#include <stdio.h>

struct Student {
char matrikl[6];
char shortName[6];
int value1;
int value2;
int value3;
int value4;
int money;
}xStudent;

int calcMoney(int,int,int,int);

int main(void)
{
int i=0;
printf("How much students to insert!\n");
scanf("%i",&i);
    struct Student S[i];

for (int var = 0; var < i; ++var) {
    printf("insert student data\n");
    printf("Matriklinumber\n");
    scanf("%s", S[var].matrikl);
    printf("Student name\n");
    scanf("%s", S[var].shortName);
    printf("Insert values!\n");
    scanf("%i%i%i%i",&S[var].value1,&S[var].value2,&S[var].value3,&S[var].value4);
    S[var].money=calcMoney(S[var].value1,S[var].value2,S[var].value3,S[var].value4);;
}

FILE*sourcefile;
sourcefile=fopen("text.txt","ab+");

for (int var = 0; var < i; ++var) {
    fwrite(&S[var],sizeof(struct Student),1,sourcefile);
}
fclose(sourcefile);


sourcefile=fopen("text.txt","rb+");
struct Student A[i];

if (sourcefile==NULL) perror ("Error opening file");
          else
          {
                  int k=0;
                  while (fgetc(sourcefile) != EOF) {
                  fread(&A[k],sizeof(struct Student),1,sourcefile);
                  k++;
                  }
          }
fclose(sourcefile);
return 0;
}

int calcMoney(int xvalue1, int xvalue2, int xvalue3, int xvalue4)
{
int Sum = xvalue1+xvalue2+xvalue3+xvalue4;
if(Sum==20)
    return 100;
else
    if(Sum>=16 && Sum<20)
        return 75;
    else return 0;
}

3 个答案:

答案 0 :(得分:1)

你有正确的想法,但这应该可以解决你的问题。

for (int var = 0; var < i; ++var) {
    fwrite(&S[i], sizeof(struct Student), 1, sourcefile);
}

fwrite语句后sizeof中的参数1表示您一次只想添加一个学生。

请参阅fwrite的文档:http://www.cplusplus.com/reference/cstdio/fwrite/

还有:

          while (fgetc(sourcefile) != EOF) {
          fread(&A[k], sizeof(struct Student), 1, sourcefile);
          k++;
          }

请参阅fread的文档:http://www.cplusplus.com/reference/cstdio/fread/

我知道这是cplusplus网站,但它是我能找到有关这些功能的优秀文档的唯一地方。

此外,下面的数组初始化为0个元素:

struct Student A[k];

您可能希望尝试为此管理链接列表。

最终可能会看起来像:

struct StudentList {
    struct Student* student;
    struct StudentList* next;
};


struct StudentList* students = NULL;

while(!feof(sourcefile)) {
    struct StudentList* newlink = malloc(sizeof(struct StudentList));
    newlink->student = malloc(sizeof(struct Student));
    newlink->next = NULL;

    fread(newlink->student, sizeof(struct Student), 1, sourcefile); 

    if(NULL != students) {
        struct StudentList* iter;
        for(iter=students;
            NULL != iter->next;
            iter = iter->next); // iterate to last link

        iter->next = newlink; // add new link to the end
    } else students = newlink; // add new link to the beginning
}



然后要释放你的清单,只需使用:

struct StudentList* iter, *head;
for(iter=students;
    NULL != iter;)
{
    head = iter;
    free(iter->student);
    free(iter);
    iter = head;
}

答案 1 :(得分:0)

错误发生在数组A的声明中。

struct Student A[k];

K = 0;所以你得到错误,因为A [1]左右没有定义数组。 将声明更改为

struct Student A[i];

然后如果代码和语法的其余部分没问题就应该运行。

答案 2 :(得分:0)

将fwrite行修复为:

fwrite(&S[i], sizeof(struct Student), 1, sourcefile);