【问题标题】:read structure from binary file having pointer pointed to memory从具有指向内存的指针的二进制文件中读取结构
【发布时间】:2019-10-02 15:15:47
【问题描述】:
struct st {
        char *p;
        int len;
};

这是我需要写入二进制文件的结构,以及保存在

中的字符串

char *p

我应该用 char 数组数据编写一个二进制文件。写入二进制文件后。也应该能够从二进制文件中以相同的结构读取它。

我尝试使用 FSEEK_END 来获取二进制大小,并根据文件大小进行 fread,但它没有保存字符串。请建议。任何帮助/建议/指针将不胜感激。

提前致谢。

示例代码:

 struct st {
         char *p;
         int len; 
 };

 struct st varr;
 varr.len = 100;
 varr.p = new char[gen];
 strcpy(varr.p, "Hello World");

 FILE *p;
 p=fopen("address","wb");
 fwrite(&varr,sizeof(struct st),1,p);
 fclose(p); 

这会将指向二进制文件的指针写给我。但我想在这里写整个字符串,但重点是,它应该用一个 fwrite 完成。

【问题讨论】:

  • 发布您尝试过的代码。不看代码就不可能知道问题所在。
  • @AndrewHenle 感谢您的回复。请检查我的代码
  • 如果您想通过一次 fwrite 调用写入数据,您需要在内存中使用合适格式的数据构造一个缓冲区,如下面的答案所述。您需要写入字符串数据,而不是指针,并且您需要知道长度,在使用该结构的一次 fwrite 调用中这两者都不可能。
  • 你应该为这段代码选择一种看起来像 C 的语言。
  • 您正在将指针值写入文件。这没有意义。请先阅读 C 教科书中处理指针的章节。

标签: c++ c pointers structure fread


【解决方案1】:

将其写入二进制文件是没有用的。一个文本文件就足够了。

但是,如果这是你的家庭作业(或其他),我建议你按照以下步骤进行:

  • 将长度写为整数;

  • 写入字符串的len 字节。这不包括终止空值。

回读时:

  • 读取整数长度;

  • 分配这个长度的内存加上一个字节

  • 将字符串读入内存并添加终止符

用这个长度和指向分配内存的指针填充你的结构。


在您的 cmets 中,您不断迭代您想要在一个步骤中读取和写入。 用你当前的数据结构是不可能的,因为字符串总是在内存中的其他地方,fwrite 只能写入一个连续的内存块。

但是,您是否会将数据结构更改为:

struct st{
    char p[128];
    int len;
};

那么你可以一次写入和读取,因为现在结构是一个连续的内存块。但现在字符串被限制在这 128 个字节(或任何大小)。

【讨论】:

  • 感谢您的回复。有什么方法可以一步写完吗?并一步阅读。因为,循环中的几个文件需要 2-3 个步骤。如果它可以在一次读取和写入中发生,将优化我的代码。
  • 废话。 “优化我的代码”。你只是懒惰打字?以上是继续的方法。
  • @VishwadeepSingh 你在问如何做基本的 IO。不用担心优化。
  • @AndrewHenle 不,一步完成 fwrite 是我的目标,以及保存在 char * 中的字符串
  • @VishwadeepSingh 你知道fwrite() 是如何工作的以及如何优化它吗?你知道你的文件系统是如何工作的以及如何优化它吗?你知道你的磁盘控制器是如何工作的,以及如何优化你做 IO 的方式来利用它们的特殊性能特征吗?你知道你的磁盘本身是如何工作的吗?如果你这样做了,你知道你的“优化”IO 会多快吗? 编写清晰易懂的代码。在您解决已知的性能问题之前不要担心优化。那如果是 IO 问题,就去买个更快的磁盘吧。
【解决方案2】:

我建议先保存 strlen(p),然后保存 char *p 指向的所有字符。如果您尝试按原样 fwrite 结构,您将最终(在文件中)获得地址的值,并重新调整为第一个字符。您不想保存第一个字符的地址,是吗?

【讨论】:

  • 不保存地址无济于事。因此,我正在寻找一种方法将整个结构写入一个 fwrite 中的二进制文件,以及字符串。我有什么办法吗
  • char *改成char []?
  • 我无法更改结构
  • @VishwadeepSingh 那么你必须有两个fwrite
  • 就没有别的办法了吗? @kiranBiradar
【解决方案3】:

如果您非常担心没有两个fwrite,您可以使用零长度数组的包装结构。

 struct st_wrap {
         int len; 
         char p[0];
 };

struct st_wrap *temp= malloc (sizeof (struct st_wrap ) + strlen(varr.p)+1);
temp->len = strlen(varr.p);

//Copy the data
strcpy(temp->p,varr.p);

//Then write it to file
fwrite(temp,sizeof(struct st_wrap)+strlen(varr.p),1,p);

【讨论】:

  • 这是您的答案,因此您可以自行寻找解决方案。可以使用与写入部分类似的技巧来完成。
【解决方案4】:

假设您已将长度和字符串写入二进制文件:

FILE* fp = fopen("file.bin", "wb");

/* writing */
st str = { .p = "foo", .len = 3 };
fwrite((char*)(&str.len), sizeof(str.len), sizeof(str.len), fp);
fwrite(str.p, str.len, str.len, fp);

您现在可以(在不同的上下文中)将文件中的内容读取到结构对象中:

FILE* fp = fopen("file.bin", "rb");
st str;
/* read length */
fread((char*)&str.len, sizeof(str.len), sizeof(str.len), fp);
/* allocate enough space */
str.p = malloc((str.len + 1) * sizeof(char));
/* read string */
fread(str.p, str.len + 1, str.len + 1, fp);

使用完p,记得释放内存:

free(str.p);

【讨论】:

    【解决方案5】:

    我尝试了很多方法,但@kiran Biradar 的回答对我帮助很大。因此在这里显示工作代码。

    WriteBinaryFile.cpp

        struct st_wrap {
                int len;
                int crc;
                char p[0]; 
        };
    
    
        int main ()
        {
                char p[100] = "Hello World";
                struct st_wrap *temp= (struct st_wrap*) malloc (sizeof (struct st_wrap ) + strlen(p)+1);
                temp->len = strlen(p);
                temp->crc = 400;
                strcpy(temp->p,p);
                cout << temp->p << endl;
                cout << temp->len << endl;
                cout << temp->crc << endl;
    
                FILE *p1;
                p1=fopen("binary.dat","wb");
                fwrite(temp,sizeof(struct st_wrap)+strlen(p),1,p1);
                fclose(p1);
    
        }
    

    ReadBinaryFile.cpp

    struct st_wrap {
            int len;
            int crc;
            char p[0];
    };
    
    
    int main ()
    {
            struct st_wrap *vw;
            FILE *f=fopen("binary.dat","rb");
            fseek(f, 0, SEEK_END);
            long int filesize = ftell(f);
            fseek(f, 0, SEEK_SET);
            vw = (struct st_wrap*) malloc (filesize);
            fread(vw,filesize,1,f);
            cout << vw->len << endl;
            cout << vw->p << endl;
            cout << vw->crc << endl;
            return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-04
      • 2012-07-16
      • 1970-01-01
      • 1970-01-01
      • 2020-12-11
      • 1970-01-01
      相关资源
      最近更新 更多