C 将二进制序列化转换为人类可读的序列化

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[

我正在将一个程序转换为文件,该程序用于对一个结构进行二进制转储,并使用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 );
    }
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”并不是您所认为的那样。它在这里不应该有害,但它会跳过一段时间