【问题标题】:how I correctly read struct from a file?我如何正确地从文件中读取结构?
【发布时间】:2018-03-12 19:54:14
【问题描述】:

我有这种结构:

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

这是我的程序的一部分。在输入过程中(当我在我的文件上写入数据时)我没有任何问题(使用 fread)但我在读取它时遇到了一些问题。

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

在我调用 seach_m 时,我会这样做:

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

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

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

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

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

(如果我只使用“r”,它也不起作用) argv[1] 是我的文件名

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

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

【问题讨论】:

  • 你是如何打开你的文件的?你用的是同一个手柄吗?我们需要在这里调用上下文。
  • search_m() 函数应该做什么?阅读并返回多个还是只返回一个?
  • @JohnnyMopp 假设在文件中找到一个结构体,其 b 参数等于传递给 c 的 char 字符串并打印出来
  • @Ofey 听起来这就是search_s() 函数。问题:您是否在其他地方阅读该文件?是否需要rewind该文件才能再次搜索。
  • 如果您希望您的代码可移植地工作并且独立于字节顺序、填充等,请考虑使用序列化库,例如我自己的 (github.com/Erlkoenig90/uSer)。如果格式不固定,其他几个也是合适的。

标签: c file


【解决方案1】:

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

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

【讨论】:

  • 这不起作用。我不知道为什么它不从文件中读取任何数据(使用您或我的代码)
  • @Ofey,这不是minimal reproducible example。您必须将其简化为 minimal 示例。
【解决方案2】:

这就是您将结构读取和写入文件的方式。然后您应该能够使用fopen 打开您的文件,并为您的每个数据结构调用read_datawrite_data。一旦read_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);   
}

【讨论】:

    猜你喜欢
    • 2021-02-01
    • 2022-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-06
    • 2022-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多