简体   繁体   English

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

[英]Converting binary serialization to human-readable serialization

I'm converting a program that used to do a binary dump of a struct to file and read that binary struct back in using fread. 我正在将用于对结构进行二进制转储的程序转换为文件,然后使用fread读取该二进制结构。 I want to convert it to creating and reading human readable data files, which of course means I need to format the data and such. 我想将其转换为创建和读取人类可读的数据文件,这当然意味着我需要格式化数据等。

The creation of the data files in ascii went without a hitch. 在ascii中创建数据文件毫不费力。 I switched from using fwrite to using fprintf with a format specified ending with \\n for new line. 我从使用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 );
    }

This worked just fine. 这工作得很好。 you can see the old fwrite is commented out now. 您可以看到旧的fwrite现在已被注释掉。

I was hoping that reading the file would be just as easy, but it doesn't seem to be working, and I'm unable to debug it because I have a weird memory leak with Freetype in debug builds that prevents me from stepping into this code. 我希望读取文件同样容易,但是似乎无法正常工作,而且我无法调试它,因为我在调试版本中使用Freetype发生了奇怪的内存泄漏,无法进入码。 Here's the code that reads from the file. 这是从文件读取的代码。

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;

        }

There's a bit of other checking before pFile is opened and load is a bool that is set if we're going to do more than just see if a file exists. 在打开pFile之前,还有一些其他检查,如果我们要做的不只是查看文件是否存在,还要设置load是一个布尔值。 If it matters, all the values of the FlightInfo struct are float except for local_x, local_y, and local_z which are double. 如果重要的话,FlightInfo结构的所有值都是float,除了local_x,local_y和local_z均为double之外。 Is there something that stands out as obviously wrong here? 这里有什么明显不对的地方吗? It compiles and runs without error until this block of code is called, then it just crashes. 它会编译并无错误运行,直到调用此代码块,然后它才崩溃。

It does not matter to fprintf whether you pass a float or a double due to the default promotions performed for variadic arguments. 由于对可变参数的默认提升, fprintf传递float还是double float都没有关系。

But it matters very much for fscanf whether you pass a float* or double* : 但是无论您传递float*还是double*对于fscanf非常重要:

See http://man7.org/linux/man-pages/man3/scanf.3.html for the flags: 有关标志,请参见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) . l表示转换将是d,i,o,u,x,X或n之一,并且下一个指针是指向long int或unsigned long int(而不是int)的指针, 或者转换将是e,f或g中的一个,下一个指针是指向double(而不是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字符等效于L。如果与%c或%s一起使用,则相应的参数分别被视为指向宽字符或宽字符字符串的指针。

Actually, you should read that whole man-page, there are other interesting pitfalls. 实际上,您应该阅读整个手册页,还有其他有趣的陷阱。

As an aside, the l -modifier has no effect for fprintf with a floating-point-specifier. fprintf一句,带有浮点说明符的l修饰符对fprintf无效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM