将二进制序列化转换为人类可读的序列化
Converting binary serialization to human-readable serialization
我正在将一个用于将结构的二进制转储文件转换为文件并使用 fread 读回该二进制结构的程序。我想将其转换为创建和读取人类可读的数据文件,这当然意味着我需要格式化数据等。
ascii 数据文件的创建很顺利。我从使用 fwrite 切换到使用 fprintf,其格式指定以 \n 结尾作为新行。
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 );
}
这很好用。你可以看到旧的 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;
}
在打开 pFile 之前还有一些其他检查,如果我们要做的不仅仅是查看文件是否存在,load 是一个布尔值。如果重要的话,FlightInfo 结构的所有值都是浮点数,除了 local_x、local_y 和 local_z 是双精度值。这里有什么明显错误的地方吗?它编译和运行没有错误,直到调用此代码块,然后它才崩溃。
由于对可变参数执行的默认提升,无论您传递 float
还是 double
对 fprintf
都没有关系。
但是对于 fscanf
来说,你传递 float*
还是 double*
非常重要:
有关标志,请参阅 http://man7.org/linux/man-pages/man3/scanf.3.html:
The following type modifier characters can appear in a conversion
specification:
l
Indicates either that the conversion will be one of d, i, o,
u, x, X, or n and the next pointer is a pointer to a long int
or unsigned long int (rather than int), or that the conversion
will be one of e, f, or g and the next pointer is a pointer to
double (rather than float). Specifying two l characters is
equivalent to L. If used with %c or %s, the corresponding
parameter is considered as a pointer to a wide character or
wide-character string respectively.
实际上,您应该阅读整个手册页,还有其他有趣的陷阱。
顺便说一句,l
-修饰符对带有浮点说明符的 fprintf
没有影响。
我正在将一个用于将结构的二进制转储文件转换为文件并使用 fread 读回该二进制结构的程序。我想将其转换为创建和读取人类可读的数据文件,这当然意味着我需要格式化数据等。
ascii 数据文件的创建很顺利。我从使用 fwrite 切换到使用 fprintf,其格式指定以 \n 结尾作为新行。
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 );
}
这很好用。你可以看到旧的 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;
}
在打开 pFile 之前还有一些其他检查,如果我们要做的不仅仅是查看文件是否存在,load 是一个布尔值。如果重要的话,FlightInfo 结构的所有值都是浮点数,除了 local_x、local_y 和 local_z 是双精度值。这里有什么明显错误的地方吗?它编译和运行没有错误,直到调用此代码块,然后它才崩溃。
由于对可变参数执行的默认提升,无论您传递 float
还是 double
对 fprintf
都没有关系。
但是对于 fscanf
来说,你传递 float*
还是 double*
非常重要:
有关标志,请参阅 http://man7.org/linux/man-pages/man3/scanf.3.html:
The following type modifier characters can appear in a conversion specification:
l
Indicates either that the conversion will be one of d, i, o, u, x, X, or n and the next pointer is a pointer to a long int or unsigned long int (rather than int), or that the conversion will be one of e, f, or g and the next pointer is a pointer to double (rather than float). Specifying two l characters is equivalent to L. If used with %c or %s, the corresponding parameter is considered as a pointer to a wide character or wide-character string respectively.
实际上,您应该阅读整个手册页,还有其他有趣的陷阱。
顺便说一句,l
-修饰符对带有浮点说明符的 fprintf
没有影响。