我必须处理代码,其中一方使用FILE*
将信息写入文件,另一方面使用ifstream
读取。
我尝试编译一个显示与原始代码相同行为的虚拟代码:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
int main()
{
FILE* outFile = fopen("testFile", "w");
char* posBuf = NULL;
unsigned int counter = 0;
posBuf = (char*) malloc( sizeof(int) + 2*sizeof(double) );
int iDummy = 123;
memcpy(posBuf+counter, (const void*) &iDummy, sizeof(int));
counter += sizeof(int);
double dDummy = 456.78;
memcpy(posBuf+counter, (const void*) &dDummy, sizeof(double));
counter += sizeof(double);
dDummy = 111.222;
memcpy(posBuf+counter, (const void*) &dDummy, sizeof(double));
fputs(posBuf, outFile);
fclose(outFile);
/////////////////////
std::ifstream myfile;
myfile.open("testFile", std::ios::in|std::ios::binary);
myfile.seekg (0, std::ios::end);
unsigned int length = myfile.tellg();
myfile.seekg (0, std::ios::beg);
char* posBuf2 = (char*) malloc( length );
myfile.read(posBuf2, length);
counter = 0;
int idummy = 0;
memcpy((void*) &idummy, posBuf2+counter, sizeof(int));
counter += sizeof(int);
printf("read integer: %u\n", idummy);
double ddummy = 1.0;
memcpy((void*) &ddummy, posBuf2+counter, sizeof(double));
counter += sizeof(double);
printf("read double: %f\n", ddummy);
ddummy = 1.0;
memcpy((void*) &ddummy, posBuf2+counter, sizeof(double));
counter += sizeof(double);
printf("read double: %f\n", ddummy);
myfile.close();
/////////////////////
FILE* inFile = fopen("testFile", "r");
char* posBuf3 = NULL;
unsigned int c = 0;
while ( ! feof (inFile) )
{
posBuf3 = (char*) realloc((void*) posBuf3, c+4);
fgets(posBuf3+c, 4, inFile);
c += 4;
}
idummy = 0;
memcpy((void*) &idummy, posBuf, sizeof(int));
printf("read again integer: %u\n", idummy);
ddummy =1.0;
memcpy((void*) &ddummy, posBuf+sizeof(int), sizeof(double));
printf("read again double: %f\n", ddummy);
ddummy =1.0;
memcpy((void*) &ddummy, posBuf+sizeof(int)+sizeof(double), sizeof(double));
printf("read again double: %f\n", ddummy);
return 0;
}
我得到的输出是:
read integer: 123
read double: 0.000000
read double: 0.000000
read again integer: 123
read again double: 456.780000
read again double: 111.222000
正如您所看到的,仅当我使用FILE*
来读取文件时,反序列化才有效。
问题:对该行为有何解释?
谢谢!
已更新:
1)使用ifstream
std::ios::in|std::ios::binary
2)修复malloc
答案 0 :(得分:2)
发布代码的一些问题:
posBuf
分配的内存范围(1 int
和2 double
被复制到内存中,但只分配sizeof(int) + sizeof(double)
) ,这是未定义的行为。fputs()
将其参数视为以空字符结尾的字符串,因此在遇到空字符时将停止写入。以二进制模式打开文件并使用fwrite()
而不是将其输入视为空终止字符串。代码还有其他几个问题;
可避免的显式动态内存管理(不要介意malloc()
和realloc()
)。只需替换为:
char posBuf[sizeof(int) + 2 * sizeof(double)];
while (!feof(inFile))
。