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

时间:2015-03-03 15:36:16

标签: c printf fopen fread scanf

我正在将一个用于对结构进行二进制转储的程序转换为文件,然后使用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之前还有一些其他检查,如果我们要做的不仅仅是查看文件是否存在,那么加载是设置的bool。如果重要,FlightInfo结构的所有值都是float,除了local_x,local_y和local_z是double。有什么东西在这里显然是错误的吗?它会在没有错误的情况下进行编译和运行,直到调用此代码块,然后它才会崩溃。

1 个答案:

答案 0 :(得分:2)

由于为可变参数执行的默认促销,fprintf是否传递floatdouble无关紧要。

fscanf对于float*double*传递是否非常重要:

请参阅http://man7.org/linux/man-pages/man3/scanf.3.html标志:

  

以下类型修饰符可以出现在转化中          规格:

     

l表示转换将是d,i,o之一,                 u,x,X或n,下一个指针是指向long int的指针                 或unsigned long int(而不是int),或转换                 将是e,f或g之一,下一个指针是指针                 加倍(而非浮动)。指定两个l字符是                 相当于L.如果与%c或%s一起使用,则相应                 参数被视为指向宽字符的指针                 分别是宽字符串。

实际上,你应该阅读整个人页,还有其他有趣的陷阱。

顺便说一句,l - 修饰符对具有浮点指定符的fprintf没有影响。