I am trying to open a .dat binary file in C as an exercise, however when I try to print out the contents of the file, I receive symbols instead of numbers.
Here is the code on how I read the .dat file:
int main() {
errno_t status;
std::FILE *input_file;
status = fopen_s(&input_file, filename, "rb");
if (status == 0) {
std::string content;
std::fseek(input_file, 0, SEEK_END);
content.resize(std::ftell(input_file));
std::rewind(input_file);
std::fread(&content[0], 1, content.size(), input_file);
std::fclose(input_file);
for (int i = 0; i < 10; i ) {
std::cout << content[i];
}
}
return 0;
}
I also tried it using C fstream
.
int main() {
std::ifstream input_file(filename, std::ios::in | std::ios::binary);
if (input_file) {
std::string content;
input_file.seekg(0, std::ios::end);
content.resize(input_file.tellg());
input_file.seekg(0, std::ios::beg);
input_file.read(&content[0], contents.size());
input_file.close();
for (int i = 0; i < 10; i ) {
std::cout << content[i];
}
}
return 0;
}
When I try to print the content of content
, it returns ⁿ\|Cⁿ\|Cⁿ\
(for the first 10 elements), which corresponds to the first 10 bytes of the file: fc 5c 7c 43 fc 5c 7c 43 fc 5c
(according to a Hex Editor).
I could easily open the file in Python by using
data = numpy.fromfile(filename, "=f")
and returns the following (which I expect),
array([252.36322, 252.36322, 252.36322, ..., 239.38304, 239.38304,
239.38304], dtype=float32)
I also looked into the number of bytes each element should have using Python, and it returned 4, which matches with the output of std::ftell(input_file)
(the file should have 36 million points), but I tried changing 1
to 4
in the line std::fread(&content[0], 1, content.size(), input_file);
and it returns an empty content
. Also, as far as I know, the file doesn't contain any headers, so I think the data should begin at the very first bit.
So, how could I open and read the .dat file in C so that it returns the same value as Python?
Thank you in advance.
CodePudding user response:
The loop
for (int i = 0; i < 10; i ) {
std::cout << content[i];
}
is printing the data by interpreting the data as representing the character codes of invidual characters. However, this is not what the data represents. The data actually represents single-precision floating-point numbers. Therefore, you should interpret it as such:
for (int i = 0; i < 10; i ) {
float f;
std::memcpy( &f, content.data() i * sizeof f, sizeof f );
std::cout << f << '\n';
}
Note that you must #include <cstring>
in order to use std::memcpy
.
CodePudding user response:
You should use C 's fstream instead of C functions as such:
#include <iostream>
#include <fstream>
#include <string>
int main()
{
std::ifstream in("batFile.bat");
if (in)
{
std::string content;
std::string line;
while (std::getline(in, line))
{
content = line '\n';
}
std::cout << content;
}
return 0;
}
batFile.bat
12
12
13
13
output
12
12
13
13
As you can see this code works perfectly fine, you may modify it as per your requirements :)