C 将二进制序列化转换为人类可读的序列化
我正在将一个程序转换为文件,该程序用于对一个结构进行二进制转储,并使用fread将该二进制结构读回。我想将其转换为创建和读取人类可读的数据文件,这当然意味着我需要格式化数据等等 以ascii格式创建数据文件的工作进展顺利。我从使用fwrite切换到使用指定格式的fprintf,新行以\n结尾C 将二进制序列化转换为人类可读的序列化,c,printf,fopen,fread,scanf,C,Printf,Fopen,Fread,Scanf,我正在将一个程序转换为文件,该程序用于对一个结构进行二进制转储,并使用fread将该二进制结构读回。我想将其转换为创建和读取人类可读的数据文件,这当然意味着我需要格式化数据等等 以ascii格式创建数据文件的工作进展顺利。我从使用fwrite切换到使用指定格式的fprintf,新行以\n结尾 FPFPF = fopen( flightStr, "w+" ); if (FPFPF != NULL) { for ( i = 0; i < FlightInfo[
FPFPF = fopen( flightStr, "w+" );
if (FPFPF != NULL)
{
for ( i = 0; i < FlightInfo[flightnum].endFrameIndex; i++)
{
FlightEntries[flightnum][i].local_z += DeltaAlt;
//if (fwrite (&FlightEntries[flightnum][i], sizeof (FLIGHT_ENTRY_TYPE), 1, FPFPF) !=1)
if (fprintf (FPFPF, "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f\n",
FlightEntries[flightnum][i].local_x,
FlightEntries[flightnum][i].local_y,
FlightEntries[flightnum][i].local_z,
FlightEntries[flightnum][i].pitch,
FlightEntries[flightnum][i].roll,
FlightEntries[flightnum][i].heading,
FlightEntries[flightnum][i].gearpos,
FlightEntries[flightnum][i].flappos,
FlightEntries[flightnum][i].speedbrakepos,
FlightEntries[flightnum][i].canopypos,
FlightEntries[flightnum][i].afterburnerOn,
FlightEntries[flightnum][i].kias,
FlightEntries[flightnum][i].time) !=1)
{
WE++;
}
}
fclose( FPFPF );
}
FPFPF=fopen(flightStr,“w+”);
如果(fpf!=NULL)
{
对于(i=0;i
这很管用。你可以看到旧的fwrite现在被注释掉了
我希望读取该文件也同样容易,但它似乎不起作用,我无法调试它,因为调试版本中有一个奇怪的Freetype内存泄漏,阻止我进入此代码。下面是从文件读取的代码
if (load)
{
for ( i = 0; i < MAX_FLIGHT_ENTRIES; i++)
{
// If the file end is found before it should be, set values to defaults
// and save the file
if (feof(pFile))
{
FlightInfo[fileIndex].endFrameIndex = i - 1;
break;
}
else
{
//fread (&FlightEntries[fileIndex][i], sizeof (FLIGHT_ENTRY_TYPE), 1, pFile);
fscanf (pFile, "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f\n",
&FlightEntries[fileIndex][i].local_x,
&FlightEntries[fileIndex][i].local_y,
&FlightEntries[fileIndex][i].local_z,
&FlightEntries[fileIndex][i].pitch,
&FlightEntries[fileIndex][i].roll,
&FlightEntries[fileIndex][i].heading,
&FlightEntries[fileIndex][i].gearpos,
&FlightEntries[fileIndex][i].flappos,
&FlightEntries[fileIndex][i].speedbrakepos,
&FlightEntries[fileIndex][i].canopypos,
&FlightEntries[fileIndex][i].afterburnerOn,
&FlightEntries[fileIndex][i].kias,
&FlightEntries[fileIndex][i].time);
}
}
FlightInfo[fileIndex].endFrameIndex = i - 1;
}
if(加载)
{
对于(i=0;i
在打开pFile和load之前还有一些其他的检查,如果我们要做的不仅仅是查看文件是否存在,那么就要设置bool。如果重要的话,FlightInfo结构的所有值都是float,除了local_x、local_y和local_z是双精度的。这里有什么明显的错误吗?它编译并运行时不会出错,直到调用了这段代码,然后它就崩溃了。由于对可变参数执行的默认升级,您是否传递了
float
或double
,与fprintf
无关
但是,对于fscanf
来说,传递一个float*
还是double*
非常重要:
有关标志,请参见:
以下类型修改器字符可以出现在转换中
规格:
l
表示转换将是d、i、o中的一个,
u、 下一个指针是指向长整型的指针
或无符号长整型(而非整型),或转换
将是e、f或g中的一个,下一个指针是指向
双精度(而非浮动)。需要指定两个l字符
相当于L。如果与%c或%s一起使用,则相应的
参数被视为指向宽字符或
分别为宽字符串
实际上,你应该阅读整个手册页,还有其他有趣的陷阱
另一方面,
l
-修饰符对于带有浮点说明符的fprintf
无效。我可能错了,但我的第一次尝试是在这里使用parantasis:&FlightEntries[fileIndex][I]。local_x
=>&(FlightEntries[fileIndex][I]。local ux)
。我总是忘记计算顺序,使用parantisis不会错^^@UniversE:这些参数显然是多余的。无论它们是float
还是double
,由于默认升级,这都与fscanf
无关。我建议使用fscanf()的返回代码,这是转换的字段数,以查看您在运行时得到的正是您所期望的。此外,fscanf字符串中的“\n”并不是您所认为的那样。它在这里不应该有害,但它会跳过一段时间