Reputation: 53
I want to read this binary file and print the numbers on the screen but it is printing weird characters. I generated this binary file from MATLAB. How can I display the data properly?
#include <iostream>
#include <fstream>
using namespace std;
ifstream::pos_type size;
char * memblock;
int main ()
{
ifstream file ("seg.bin", ios::in|ios::binary|ios::ate);
if (file.is_open())
{
size = (int)file.tellg();
memblock = new char [size];
file.seekg (0, ios::beg);
file.read (memblock, size);
file.close();
cout << "the complete file content is in memory";
for (int i=0;i<size;i++)
{
cout<<memblock[i]<<endl;
}
}
else cout << "Unable to open file";
return 0;
}
Upvotes: 2
Views: 1469
Reputation: 13298
You're printing char
s to the output, the representation of the char
in the output is a character, and if the character you're sending to std::cout
isn't printable you'll see nothing or in some cases you'll see weird characters (or in some cases a beep sound!).
Try to cast the char
value to int
:
std::cout << static_cast<int>(memblock[i]) << std::endl;
^^^^^^^^^^^^^^^^
The way you're iterating-printing the data you'll only get data of 8bits size (or the size you char
is), let's supose you have the following data on your file:
00000FFF
Your output will be:
0
0
15
255
But if you're working with data of other sizes (int
for example) you will expect an output of 4095
(or 0
and 4095
if your data is 16bits wide).
If is your case, try to read the data into an array of the data you're expecting:
const ifstream::pos_type size = file.tellg(); // do not cast the size!
const size_t elements = size / sizeof(int); // <--- beware of the sizes!
memblock = new int [elements]; // Elements, not size
for (int i = 0; i < elements; ++i) // Elements! not size
{
std::cout << memblock[i] << std::endl;
}
Another tips:
size
and elements
as const (you're not going to change them after reading): This shows to you and your workmates your intention to treat this variables as read-only.size
to int
, use the type of return of tellg()
or use auto
: const auto size = file.tellg();
: Why cast to another type? Use the same of the function you're calling! Casts may lead to overhead.Upvotes: 0
Reputation: 537
memblock is of type char that is why cout will make char print(ascii characters). What you want to in this case is to reinterpret_cast the memblock pointer to the pointer of the type that you need. Say you need double:
size = (int)file.tellg();
memblock = new char [size];
file.seekg (0, ios::beg);
file.read (memblock, size);
file.close();
double * fileContent = reinterpret_cast<double *>(memblock);
cout << "the complete file content is in memory";
int sizeOfFileContent = sizeof(memblock)/sizeof(double);
for (int i=0; i<sizeOfFileContent; i++)
{
cout<<fileContent[i]<<endl;
}
Use only one pointer to reclaim memory, not to try to delete it multiple times!
Upvotes: 0
Reputation: 63481
You need to know what the datatype stored in the file is. Let's say it's double
. In that case, you can do this:
for (int i = 0; i < size; i += sizeof(double))
{
cout << *(double*)&memblock[i] << endl;
}
The other way to go about it is to read directly into an array of double
to begin with. Will leave that as an exercise.
Upvotes: 0