我如何从文件中正确读取结构?

时间:2018-03-12 19:54:15

标签: c file

我有这种结构:

  typedef struct {
  char a[MAX];
  char b[MAX];
  int c;
  } mys;

并且这个功能:

mys* search_m(FILE *fp, int m)
  {
    mys* s;
    s=(mys *)malloc(sizeof(mys));
    if(s){
      for(int i=0;i<m;i++)
        fread(s,sizeof(mys),1,fp);
    }else{
      printf("Error during allocation\n");
    }
    return s;
  }


  void search_s(FILE *fp, char *c)
  {
    mys s;
    int count=0;

    while(fread(&s,sizeof(mys),1,fp)==1){

        if(strcmp(s.b,c)==0){
          show_s(s,count);

        }
        count++;
    }    
     return;
  }

这是我计划的一部分。在输入fase期间(当我在我的文件上写入数据时)我没有任何问题(使用fread)但是我在阅读它时遇到了一些问题。

我的函数 search_s 每次调用时都会执行并找到该值,但 search_m 函数似乎无法读取我文件中的数据因为它与我在 search_s 上做的几乎相同,我不知道我的错误在哪里。

在我打电话给 seach_m 的时候,我这样做:

s=*search_ID(f_ptr,m);
show_s(s,m);

我不认为问题是主要的,因为 search_m 功能中的fread不会加载任何数据(它会在第一次尝试时停止)。

我的错误在哪里?我以为没事 在调用此函数之前PS我打开文件并检查错误,然后关闭文件。

编辑: 我用这个打开文件:

f_ptr=fopen(argv[1],"rb");

(如果我只使用&#34; r&#34;)它也不起作用。 argv [1]是我的文件的名称

PS m是我想要读取的文件中的元素编号。 (我每次看到一个单独的块,我都没有得到m-esimo元素)

我的文件只包含该类型的结构。

2 个答案:

答案 0 :(得分:0)

  

以下行没有分配足够的内存。

s=(mys *)malloc(sizeof(mys));

您正在为对象分配内存。因此,您访问的内存比分配的内存多,这会导致未定义的行为。

您需要为m个对象分配内存。

s = malloc(sizeof(mys)*m);

请参阅Do I cast the result of malloc?,了解为什么不应该转换malloc的返回值。

另外,请确保您已读入已分配内存的相应插槽。

mys* search_m(FILE *fp, int m)
{
  mys* s = malloc(sizeof(mys)*m);
  if(s){
    for(int i=0;i<m;i++)
      fread(s+i, sizeof(mys), 1, fp);  // Use s+i
  }else{
    printf("Error during allocation\n");
  }
  return s;
}

您可以将其压缩为仅调用一次fread

mys* search_m(FILE *fp, int m)
{
  mys* s = malloc(sizeof(mys)*m);
  if(s){
    fread(s, sizeof(mys), m, fp);
  }else{
    printf("Error during allocation\n");
  }
  return s;
}

答案 1 :(得分:0)

这是您如何读取和写入文件的结构。然后,您应该能够使用fopen打开文件,并为每个数据结构调用read_datawrite_dataread_data返回0后,它已达到EOF。但这可能容易出错,因为这取决于结构的大小。如果应用程序版本之间的大小发生变化,则可能无法正确反序列化结构。

struct st_data 
{
    char str[25];
    int i;
    int j;
};

typedef struct st_data data_t;

size_t write_data(data_t *data, FILE *stream)
{
    return fwrite(data, sizeof(*data), 1, stream);
}

size_t read_data(data_t *data, FILE *stream)
{
    return fread(data, sizeof(*data), 1, stream);
}

void search(char *str, FILE *stream)
{
    data_t data;
    size_t n_read = read_data(&data, stream);

    while (n_read > 0)
    {
        if (strcmp(data.str, str) == 0)
        {
            // handle data
        }

        n_read = read_data(&data, stream);
    }
}

int main(int argc, char *argv[])
{
    if (argc < 2)
    {
        fprintf(stderr, "ERROR: requires a single argument");
        exit(-1);
    }

    FILE *stream = fopen("data.txt", "rb+");

    search(argv[1], stream);

    fclose(stream);

    exit(0);   
}