Home > database >  Read non-specified format file data
Read non-specified format file data

Time:07-06

I have a problem reading file data packed as binary resource. I have something like this

7ë?Vý˝‹ĺ”>˙†J˙l$í?źÔ=ć$ľ>˙†J˙(çî?Yý˝ć$ľ>˙†J˙'Šč?[ý˝"6?˙†J˙KÓć?[YČ="6?˙†J˙…?Ů?[ý˝fË$?˙†J˙4Ą×?ĄŰŞ=fË$?˙†J˙ĚúĹ?[ý˝n8?˙†J˙r„Ä?s˛…=n8?˙†J˙Ôž°?[ý˝.2??˙†J˙?š?$>Í<n8?˙†J˙ÜB›?[ý˝n8?˙†J˙#ţ‡?[ý˝fË$?˙†J˙}ű†?eâ;fË$?˙†J˙gq?[ý˝"6?˙†J˙Ëšo?Đuő»"6?˙†J˙OÄ]?[ý˝_Yż>˙†J˙ľ\?P‰Ľ_Yż>˙†J˙: W?[ý˝ ÓS>˙†J˙JeU?@3ŁĽ ÓS>˙†J˙OÄ]?[ý˝Í#=˙†J˙ľ\?

It should be numeric data 1 float - 4 bytes.

it should be "1.8376168"

First 4 bytes of file converted to hex is

07 37 EB 3F

I need some help with converting this to float.

I managed to do this using memcpy. Here is a code (You can't see first character before 7 and it's [BELL] it works in VS)

void using_memcpy(const char* s, size_t slen) {
float* f = new float[slen / sizeof(float)];
memcpy(f, s, slen / sizeof(float) * sizeof(float));
for (size_t i = 0; i < slen / sizeof(float);   i) {
    printf("%zu = %f\n", i, f[i]);
}
delete f;

}

           std::string ch = "7ë?";

       using_memcpy(ch.c_str(), ch.size());

CodePudding user response:

If your data is the binary representation of IEEE 754 floating point numbers, which it looks like it is, you can memcpy that data into a float variable.

You may need to do endianness conversion, depending on the platform you're compiling for.

Compiler explorer

// read this from a file and store it in some container.
// this is just a std::string for an easier example
const std::string raw_data = "7ë?Vý˝‹ĺ”>˙†J˙l$í?źÔ=ć$ľ>˙†J˙(çî?Yý˝ć$ľ>˙†J˙'Šč?[ý˝\"6?˙†J˙KÓć?[YČ=\"6?˙†J˙…?Ů?[ý˝fË$?˙†J˙4Ą×?ĄŰŞ=fË$?˙†J˙ĚúĹ?[ý˝n8?˙†J˙r„Ä?s˛…=n8?˙†J˙Ôž°?[ý˝.2??˙†J˙?š?$>Í<n8?˙†J˙ÜB›?[ý˝n8?˙†J˙#ţ‡?[ý˝fË$?˙†J˙}ű†?eâ;fË$?˙†J˙gq?[ý˝\"6?˙†J˙Ëšo?Đuő»\"6?˙†J˙OÄ]?[ý˝_Yż>˙†J˙ľ\?P‰Ľ_Yż>˙†J˙: W?[ý˝ ÓS>˙†J˙JeU?@3ŁĽ ÓS>˙†J˙OÄ]?[ý˝Í#=˙†J˙ľ\?";

for(size_t idx = 0;
    idx <= (raw_data.size() - 4);
    idx  = 4)
{
    static_assert(sizeof(float) == 4);

    if constexpr (std::endian::native == std::endian::big)
    {
        // need to swap endianness
        int32_t temp;
        std::memcpy(&temp, raw_data.data()   idx, 4);
        temp = byteswap(temp); //check the compiler explorer link for the implementation
        float f;
        std::memcpy(&f, &temp, 4);
        std::cout << f << std::endl;
    }
    else
    {
        float f;
        std::memcpy(&f, raw_data.data()   idx, 4);
        std::cout << f << std::endl;
    }
}
  •  Tags:  
  • c
  • Related