c - 如何将结构数组的二进制副本写入文件

标签 c arrays file pointers struct

我想将结构数组的二进制图像写入二进制文件。到目前为止我已经试过了:

#include <stdio.h>
#include <string.h>
#define NUM 256

const char *fname="binary.bin";


typedef struct foo_s {
    int intA;
    int intB;
    char string[20];
}foo_t;



void main (void)
{
    foo_t bar[NUM];

    bar[0].intA = 10;
    bar[0].intB = 999;
    strcpy(bar[0].string,"Hello World!");

    Save(bar);
    printf("%s written succesfully!\n",fname);
}

int Save(foo_t* pData)
{
    FILE *pFile;
    int ptr = 0;
    int itr = 0;

    pFile = fopen(fname, "w");
    if (pFile == NULL) {
        printf("couldn't open %s\n", fname);
        return;
    }
    for (itr = 0; itr<NUM; itr++) {
        for (ptr=0; ptr<sizeof(foo_t); ptr++)
        {
            fputc((unsigned char)*((&pData[itr])+ptr), pFile);
        }
        fclose(pFile);
    }  
}

但是编译器说 在需要整数的地方使用聚合值 fputc((unsigned char)*((&pData[itr])+ptr), pFile); 我不太明白明白为什么,我做错了什么?

谢谢!

最佳答案

问题一

使用正确的模式打开文件。

pFile = fopen(fname, "wb");

问题2

fclose 的调用在错误的地方。

for (itr = 0; itr<NUM; itr++) {
  for (ptr=0; ptr<sizeof(foo_t); ptr++)
  {
    fputc((unsigned char)*((&pData[itr])+ptr), pFile);
  }
  fclose(pFile);
}

您在写出第一个 foo_t 的数据后关闭文件。后续调用将导致未定义的行为,因为您将使用已关闭的 FILE* 调用 fputc

必须将对 fclose 的调用移出循环。

for (itr = 0; itr<NUM; itr++) {
  for (ptr=0; ptr<sizeof(foo_t); ptr++)
  {
    fputc((unsigned char)*((&pData[itr])+ptr), pFile);
  }
}
fclose(pFile);

问题3

您尝试在循环中访问字节的方式不正确。这是循环:

for (itr = 0; itr<NUM; itr++) {
  for (ptr=0; ptr<sizeof(foo_t); ptr++)
  {
    fputc((unsigned char)*((&pData[itr])+ptr), pFile);
  }
}

这是您要获取字节的行。

    fputc((unsigned char)*((&pData[itr])+ptr), pFile);
                           ^           ^
                           This is of type `foo_t*`

    fputc((unsigned char)*((&pData[itr])+ptr), pFile);
                          ^                 ^
                          This pointer arithmetic is done on `foo_t*`.
                          It is not pointer arithmetic done on `char*`.
                          You are going to run into out of bound memory access
                          very quickly.

    fputc((unsigned char)*((&pData[itr])+ptr), pFile);
                         ^                  ^
                         This is dereferencing a `foo_t*`, which
                         means it is of type `foo_t`.

由于您试图将 foo_t 转换为 unsigned char,因此出现编译器错误。

要保存foo_t,您可以采用两种方法。您可以使用 fwrite 在一次调用中保存整个 foo_t

for (itr = 0; itr<NUM; itr++) {
  fwrite(&(pData[itr]), sizeof(foo_t), 1, pFile);
}

如果您必须使用 fputc 写入每个字节,我认为这不是必需的,您将不得不稍微更改您的代码。

以下应该有效:

for (itr = 0; itr<NUM; itr++) {
  cp = (char*)&pData[itr];  // Declare char* cp in the function.
  for (ptr=0; ptr<sizeof(foo_t); ptr++)
  {
    fputc(cp[ptr], pFile);
  }
}

关于c - 如何将结构数组的二进制副本写入文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25417816/

相关文章:

c - 为什么 C 代码将大于 10 的数字返回为字母?

c - 无法将嵌套 if 转换为 if(condition1 || condition2)

c - Fork() 导致打印语句重叠

c - 为什么我从 scanf 循环中收到段错误?

c - fwrite 在 C 中向文件中写入了错误的字符

c - C语言读取文本文件

c - brk 和 sbrk 代表什么?

php - 为什么 php 数组中 null 键的值更改为 1?

arrays - 用 0 快速填充数组

python - 从 Python 的输入流加载图像