我想将结构数组的二进制图像写入二进制文件。到目前为止我试过这个:
#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);
}
}
但是编译器说aggregate value used where an integer was expected fputc((unsigned char)*((&pData[itr])+ptr), pFile);
并且我不太明白为什么,我做错了什么?
谢谢!
答案 0 :(得分:2)
问题1
使用正确的模式打开文件。
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
的数据后关闭了该文件。后续调用将导致未定义的行为,因为您将使用已关闭的fputc
来调用FILE*
。
必须将对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);
}
}
答案 1 :(得分:1)
要写入二进制文件,您需要以w + b模式打开文件。 然后使用fwrite写入文件。 它应该工作。
pFile = fopen(fname, "w+b");
而不是fputc使用fwrite。
fwrite ((foo_t *)&pData[itr], sizeof(foo_t), 1, pFile);
答案 2 :(得分:1)
确保以二进制模式打开文件。
// pFile = fopen(fname, "w");
pFile = fopen(fname, "wb");
在编制索引之前转换为char *
指针。 sizeof(pData[itr])
的原始代码索引。 [编辑]然后取消引用该类型 - 然后尝试强制转换为unsigned char
@R Sahu
//fputc((unsigned char)*((&pData[itr])+ptr), pFile);
unsigned char *p = (unsigned char *) (&pData[itr]);
fputc(p[ptr], pFile);
正如@R Sahu指出的那样:fclose()
应该移到循环之外。
次要:
推荐传递NUM
作为save()
的参数。
foo_t bar[NUM];
尚未完全初始化。
非循环解决方案
if (fwrite(pData, sizeof(*pData), NUM, pFile) == NUM) Success();
建议制作const
:`int Save(const foo_t * pData)
最好将size_t
用于ptr
&amp; itr
答案 3 :(得分:0)
我认为你需要做的只是写它。
foo_t fooarry[SOME_SIZE];
fd = open(fname, O_WRONLY);
write(fd, fooarry, SOME_SIZE * sizeof(foo_t));
更新: 如果你想使用文件流,请按以下步骤操作:
fwrite(fooarry, siezeof(foo_t), SOME_SIZE, pFile);