Home > database >  Read .dat binary file in c (depth map)
Read .dat binary file in c (depth map)

Time:11-05

I'm very new to working with binary, so I don't know how to work with such files correcty.

I recieved a .dat file. I know it's a depth map - "The depth map is an array of double written to a binary file, 64 bits in size for each number. The array is written line by line, the dimensions of the array are Width * Height, Height of lines by the Width of elements. The file contains: Height, Width, data array."

I don't know how to read double characters and make an array. I have this code:

ifstream ifs(L"D:\\kek\\DepthMap_10.dat", std::ios::binary);
char buff[1000];
ifs.seekg(0, std::ios::beg);
int count = 0;

while (!ifs.eof()) {
    ifs.read(buff, 1000);
    cout << count   << buff<< endl;
}

And as output I have something like this

914 fф╦┼p@)щ▓p╧┬p@уЖФНВ┐p@уTхk↔╝p@юS@∟x╕p@УбХоЗ┤p@☺пC7b░p@лБy>%мp@y‼i∟сзp@╚_-

What should I do to convert this into double and receive an array?

P.S. You can download file here (google disk).

CodePudding user response:

You can't use >> to read the binary data. You need to use ifs.read. There are also different floating point formats, but I assume you and the creator of the map are lucky to share the same format.

Here's an example of how it could be done:

#include <climits>
#include <fstream>
#include <iostream>
#include <vector>

int main() {
    // make sure our double is 64 bits:
    static_assert(sizeof(double) * CHAR_BIT == 64);

    // ios::binary is not really needed since we use unformatted input with
    // read()
    std::ifstream ifs("DepthMap_10.dat", std::ios::binary);
    if(ifs) {
        double dheight, dwidth;

        // read height and width directly into the variables:
        ifs.read(reinterpret_cast<char*>(&dheight), sizeof dheight);
        ifs.read(reinterpret_cast<char*>(&dwidth), sizeof dwidth);

        if(ifs) { // still ok?
            // doubles are strange to use for sizes that are integer by nature:
            auto height = static_cast<size_t>(dheight);
            auto width = static_cast<size_t>(dwidth);

            // create a 2D vector to store the data:
            std::vector<std::vector<double>> dmap(height,
                                                  std::vector<double>(width));

            // and read all the data points in the same way:
            for(auto& row : dmap) {
                for(double& col : row)
                    ifs.read(reinterpret_cast<char*>(&col), sizeof col);
            }

            if(ifs) {     // still ok?
                // print the map
                for(auto& row : dmap) {
                    for(double col : row) std::cout << col << ' ';
                    std::cout << '\n';
                }
            }
        }
    }
}
  • Related