Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   reading binary file into memory. Converting from char to uint32,float, double, ASCII strings etc (static_cast< > ?) (http://www.velocityreviews.com/forums/t754941-reading-binary-file-into-memory-converting-from-char-to-uint32-float-double-ascii-strings-etc-static_cast.html)

someone 10-15-2011 07:00 PM

reading binary file into memory. Converting from char to uint32,float, double, ASCII strings etc (static_cast< > ?)
 
Hi,

Here's my program:

==========================
#include <fstream>
#include <iostream>
#include <string>
#include <sstream>
#include <stdio.h>
//#include <boost/cstdint.hpp> // <-- I know this is not the group to
ask in, maybe unnecessary

using namespace std;


int main( int argc, const char* argv[] )
{
ifstream::pos_type fsize;
char * memblock;
ifstream infile;

cout << "Program to read SENSOR file (for FLEX5). Build on: " <<
__DATE__ << " / " << __TIME__ << endl;

infile.open("DELETEME.res", ios::in|ios::binary);

if (infile.is_open())
{
infile.seekg (0, ios::end); // go to end of file
fsize = infile.tellg();
infile.seekg (0, ios::beg); // go to beginning

cout << "Size of file is: " << fsize << " bytes." << endl;
memblock = new char [fsize];

infile.read (memblock, fsize);
infile.close();
//cout << "the complete file content is in memory" << endl;
}
else
cout << "Unable to open file" << endl;

cout << endl; // delimiter before program outputs read data

int R1_begin;
R1_begin = static_cast<typeof R1_begin> (memblock[0]);//, 1,
'uint32',endianNess);
cout << "Value = " << R1_begin << endl;

delete[] memblock;
return 0;
}
==========================

Problem:

R1_begin is the first value read from a binary file. But it's wrong!
It should be 72 but the program prints 49 out to the screen. So I
cannot continue before I get this right. The first few bytes I'm going
to read is:

R1begin = 1 byte times sizeof 'uint32' = 4 bytes
I1_I6 = 6 bytes times sizeof 'uint32' = 6x4 = 24 bytes
TEXT = 40 ASCII characters of type 'char' = 40 bytes
R1end = 1 byte times sizeof 'uint32' = 4 bytes

Total bytes read = 4+24+40+4 = 72 bytes. That's why I must read 72
bytes from the very first byte in the binary file... And I cannot
solve this! :-(

Please help (and please provide hints for reading the next few bytes
and how I should convert from data in memory into different data
types). Later I also need to convert some bytes from memblock[ ] into
floats and doubles...

I'm stuck...

And what about big endian / little endian? I'm confused. Looking
forward to hear from you!








Ian Collins 10-15-2011 08:29 PM

Re: reading binary file into memory. Converting from char to uint32,float, double, ASCII strings etc (static_cast< > ?)
 
On 10/16/11 08:00 AM, someone wrote:
> Hi,
>
> Here's my program:
>
> ==========================
> #include<fstream>
> #include<iostream>
> #include<string>
> #include<sstream>
> #include<stdio.h>
> //#include<boost/cstdint.hpp> //<-- I know this is not the group to
> ask in, maybe unnecessary
>
> using namespace std;
>
>
> int main( int argc, const char* argv[] )
> {
> ifstream::pos_type fsize;
> char * memblock;
> ifstream infile;
>
> cout<< "Program to read SENSOR file (for FLEX5). Build on: "<<
> __DATE__<< " / "<< __TIME__<< endl;
>
> infile.open("DELETEME.res", ios::in|ios::binary);
>
> if (infile.is_open())
> {
> infile.seekg (0, ios::end); // go to end of file
> fsize = infile.tellg();
> infile.seekg (0, ios::beg); // go to beginning
>
> cout<< "Size of file is: "<< fsize<< " bytes."<< endl;
> memblock = new char [fsize];
>
> infile.read (memblock, fsize);
> infile.close();
> //cout<< "the complete file content is in memory"<< endl;
> }
> else
> cout<< "Unable to open file"<< endl;
>
> cout<< endl; // delimiter before program outputs read data
>
> int R1_begin;
> R1_begin = static_cast<typeof R1_begin> (memblock[0]);//, 1,
> 'uint32',endianNess);


You can't just cast an array of char to an int and expect the right
result (unless the data is written in the same byte order as your machine).

The most convenient way to convert the byte order is to use the network
ordering functions (if your platform has them). See ntohl.

<snip>

> And what about big endian / little endian? I'm confused. Looking
> forward to hear from you!


Google "endian"

--
Ian Collins

someone 10-15-2011 09:17 PM

Re: reading binary file into memory. Converting from char to uint32,float, double, ASCII strings etc (static_cast< > ?)
 
On 15 Okt., 22:29, Ian Collins <ian-n...@hotmail.com> wrote:
> On 10/16/11 08:00 AM, someone wrote:


> > * *int R1_begin;
> > * *R1_begin = static_cast<typeof R1_begin> *(memblock[0]);//, 1,
> > 'uint32',endianNess);

>
> You can't just cast an array of char to an int and expect the right
> result (unless the data is written in the same byte order as your machine).


So how should I do it?
[to begin with, we can just assume that the data is written in the
same byte order and see if that works...]


> The most convenient way to convert the byte order is to use the network
> ordering functions (if your platform has them). *See ntohl.


Sorry, I have absolutely no idea about any network functions...
I was (pretty) sure that somebody had some code they could show here?
This "ntohl" looks a bit confusing to me - besides that, it's not
standard C++.

> <snip>
>
> > And what about big endian / little endian? I'm confused. Looking
> > forward to hear from you!

>
> Google "endian"


I did it. But what I meant is, what are your thoughts about it, when
reading a binary file like shown in my code?

Richard Damon 10-15-2011 09:35 PM

Re: reading binary file into memory. Converting from char to uint32,float, double, ASCII strings etc (static_cast< > ?)
 
On 10/15/11 3:00 PM, someone wrote:
> Hi,
>
> Here's my program:

....
> int R1_begin;
> R1_begin = static_cast<typeof R1_begin> (memblock[0]);//, 1,
> 'uint32',endianNess);
> cout<< "Value = "<< R1_begin<< endl;
>
> delete[] memblock;
> return 0;
> }
> ==========================
>
> Problem:
>
> R1_begin is the first value read from a binary file. But it's wrong!
> It should be 72 but the program prints 49 out to the screen. So I
> cannot continue before I get this right. The first few bytes I'm going
> to read is:
>
> R1begin = 1 byte times sizeof 'uint32' = 4 bytes
> I1_I6 = 6 bytes times sizeof 'uint32' = 6x4 = 24 bytes
> TEXT = 40 ASCII characters of type 'char' = 40 bytes
> R1end = 1 byte times sizeof 'uint32' = 4 bytes
>
> Total bytes read = 4+24+40+4 = 72 bytes. That's why I must read 72
> bytes from the very first byte in the binary file... And I cannot
> solve this! :-(
>
> Please help (and please provide hints for reading the next few bytes
> and how I should convert from data in memory into different data
> types). Later I also need to convert some bytes from memblock[ ] into
> floats and doubles...
>
> I'm stuck...
>
> And what about big endian / little endian? I'm confused. Looking
> forward to hear from you!
>
>

First, what is the first byte in the file? you are saying that you are
expecting it to be 72 but you are getting 49. Have you looked at the file.

Next you talk about getting R1begin which should be 4 bytes, but you are
setting it to the value of the first byte of the file (memblock[0] is
the first byte of the file) the static_cast to int is unneeded, as char
will convert to int implicitly.

Lastly, you are saying that you are expecting to read 72 bytes at the
beginning of the file, and also that you are expecting to get the value
72 from the beginning of the file, implying that R1begin is a byte count
for the record, but then don't describe the record format depending on
that value at all, and then only look at 1 byte for that info, when you
describe it as a 4 byte number.

If R1_begin ins't a data length field, why are you expecting it to have
the value 72?


Ebenezer 10-15-2011 09:41 PM

Re: reading binary file into memory. Converting from char to uint32,float, double, ASCII strings etc (static_cast< > ?)
 
On Oct 15, 4:17*pm, someone <newsbo...@gmail.com> wrote:
> On 15 Okt., 22:29, Ian Collins <ian-n...@hotmail.com> wrote:
>
> > On 10/16/11 08:00 AM, someone wrote:
> > > * *int R1_begin;
> > > * *R1_begin = static_cast<typeof R1_begin> *(memblock[0]);//,1,
> > > 'uint32',endianNess);

>
> > You can't just cast an array of char to an int and expect the right
> > result (unless the data is written in the same byte order as your machine).

>
> So how should I do it?
> [to begin with, we can just assume that the data is written in the
> same byte order and see if that works...]
>
> > The most convenient way to convert the byte order is to use the network
> > ordering functions (if your platform has them). *See ntohl.

>
> Sorry, I have absolutely no idea about any network functions...
> I was (pretty) sure that somebody had some code they could show here?
> This "ntohl" looks a bit confusing to me - besides that, it's not
> standard C++.
>


I think these files may be what you're looking for:
http://webEbenezer.net/misc/Formatting.hh
http://webEbenezer.net/misc/ReceiveBuffer.hh

They are part of this archive --
http://webEbenezer.net/misc/direct.tar.bz2 .

Brian Wood
Ebenezer Enterprises
www.webEbenezer.net

Ian Collins 10-15-2011 09:45 PM

Re: reading binary file into memory. Converting from char to uint32,float, double, ASCII strings etc (static_cast< > ?)
 
On 10/16/11 10:17 AM, someone wrote:
> On 15 Okt., 22:29, Ian Collins<ian-n...@hotmail.com> wrote:
>> On 10/16/11 08:00 AM, someone wrote:

>
>>> int R1_begin;
>>> R1_begin = static_cast<typeof R1_begin> (memblock[0]);//, 1,
>>> 'uint32',endianNess);

>>
>> You can't just cast an array of char to an int and expect the right
>> result (unless the data is written in the same byte order as your machine).

>
> So how should I do it?
> [to begin with, we can just assume that the data is written in the
> same byte order and see if that works...]
>
>> The most convenient way to convert the byte order is to use the network
>> ordering functions (if your platform has them). See ntohl.

>
> Sorry, I have absolutely no idea about any network functions...
> I was (pretty) sure that somebody had some code they could show here?
> This "ntohl" looks a bit confusing to me - besides that, it's not
> standard C++.


They are typically macros, just look them up if you want to see how they
work.

>>> And what about big endian / little endian? I'm confused. Looking
>>> forward to hear from you!

>>
>> Google "endian"

>
> I did it. But what I meant is, what are your thoughts about it, when
> reading a binary file like shown in my code?


I use the network byte order functions, that's what they are there for.

--
Ian Collins

Martin Jørgensen 10-15-2011 10:39 PM

Re: reading binary file into memory. Converting from char to uint32,float, double, ASCII strings etc (static_cast< > ?)
 
On Oct 15, 11:35*pm, Richard Damon <news.x.richardda...@xoxy.net>
wrote:
> On 10/15/11 3:00 PM, someone wrote:

==
> > I'm stuck...

>
> > And what about big endian / little endian? I'm confused. Looking
> > forward to hear from you!

>
> First, what is the first byte in the file? you are saying that you are
> expecting it to be 72 but you are getting 49. Have you looked at the file..


Good point. The first four bytes of the input file has the values:
[048h 00h 00h 00h] (hexadecimal, I used a hex editor to see this). And
0x48H = 72 decimal... I don't even know if this is little endian or
not, but what I find very strange is the number 49 then... That number
makes no sense to me (why is it adding 1, if it's printing the number
in hexadecimal? What's it thinking?)..?

> Next you talk about getting R1begin which should be 4 bytes, but you are
> setting it to the value of the first byte of the file (memblock[0] is
> the first byte of the file) the static_cast to int is unneeded, as char
> will convert to int implicitly.


Oops, sorry. You're right. I should take the first 4 bytes and convert
them into the correct integer format (which I think is unsigned int
32, but I'll have to test it). However, I still don't know exactly how
to do the conversion, sorry, I'm a bit unexperienced and it took quite
some hours to produce the first code in the original post :-(

> Lastly, you are saying that you are expecting to read 72 bytes at the
> beginning of the file, and also that you are expecting to get the value
> 72 from the beginning of the file, implying that R1begin is a byte count
> for the record, but then don't describe the record format depending on


Exactly.

> that value at all, and then only look at 1 byte for that info, when you
> describe it as a 4 byte number.


You're right. I gave up on the last and concluded that I needed some
help. I was trying to get inspired by some template<T>-code I found.
However that code only worked for reading directly from the file and
now I copied the whole file into memory, in a buffer... The correct
thing to do, is to take out the first 4 bytes and then convert that
into the relevant type. I'm currently struggling with that.

> If R1_begin ins't a data length field, why are you expecting it to have
> the value 72?


You're completely right. It is the data length field and I expect to
read in the value of 72 because: Total bytes read = 4+24+40+4 = 72
bytes. You don't happen to have some genius template that works for
this kind of problem, do you?

I'm sorry, but I still don't get the right value of 72. Here are 2 new
attempts, and I don't quite understand the output:


int R1_begin;
R1_begin = *(reinterpret_cast<char*> (&memblock));
cout << "Value = " << R1_begin << endl; // writes out: Value = 96 ??
why ?


int R1_begin; // makes no difference if I write unsigned int
R1_begin here!
memcpy(&R1_begin, &memblock[0], sizeof(R1_begin));
cout << "Value = " << R1_begin << endl; // writes out: Value =
875770417 ?? why ?


Once I get understand this and get it right, I'll look into the endian-
thing (I'm still not sure whether I have an endian problem or not)...


Martin Jørgensen 10-15-2011 10:43 PM

Re: reading binary file into memory. Converting from char to uint32,float, double, ASCII strings etc (static_cast< > ?)
 
On Oct 15, 11:45*pm, Ian Collins <ian-n...@hotmail.com> wrote:
> On 10/16/11 10:17 AM, someone wrote:


> >> The most convenient way to convert the byte order is to use the network
> >> ordering functions (if your platform has them). *See ntohl.

>
> > Sorry, I have absolutely no idea about any network functions...
> > I was (pretty) sure that somebody had some code they could show here?
> > This "ntohl" looks a bit confusing to me - besides that, it's not
> > standard C++.

>
> They are typically macros, just look them up if you want to see how they
> work.


Ok.

> >>> And what about big endian / little endian? I'm confused. Looking
> >>> forward to hear from you!

>
> >> Google "endian"

>
> > I did it. But what I meant is, what are your thoughts about it, when
> > reading a binary file like shown in my code?

>
> I use the network byte order functions, that's what they are there for.


Hmm... Based on my output to Richard - do I then have an endian
problem? Sorry I'm a bit too unexperienced to fully understand this
yet. A few replies and I think I'll understand it..

Thanks a lot for your (you, Richard and Ebenezer) help so far! :-)

someone 10-15-2011 11:12 PM

Re: reading binary file into memory. Converting from char to uint32,float, double, ASCII strings etc (static_cast< > ?)
 
On 16 Okt., 00:39, Martin Jørgensen <mjo...@gmail.com> wrote:
Sorry if it caused any confusion, but I'm the original poster (I had
two browser windows open with 2 different gmail accounts).
I now found out that my system is little endian. I also think the data
in the file is stored in little endian format (hex editor shows the
first four bytes: [048h 00h 00h 00h]) and that should correspond to an
integer value of 72, even though I cannot get it right yet... Guess
I'm casting incorrectly from char* to int.

someone 10-15-2011 11:32 PM

Re: reading binary file into memory. Converting from char to uint32,float, double, ASCII strings etc (static_cast< > ?)
 
On 16 Okt., 01:12, someone <newsbo...@gmail.com> wrote:
> integer value of 72, even though I cannot get it right yet... Guess
> I'm casting incorrectly from char* to int.


Oooops... Stupid me! I had outcommented the correct file name and used
a much smaller working file in the line: infile.open("DELETEME.res",
ios::in|ios::binary)

--- sorry guys, maybe it's too late to work for me now! :-)


Last question for today and I shall soon close the thread: Can I ask
you which of the following you think is the best to use (or suggest
alternatives)?


if (0) // my way of switching between alternate "solutions" when I
want both in the code
R1_begin = *(reinterpret_cast<unsigned char*> (&memblock[0]));//,
1, 'uint32',endianNess);
else
memcpy(&R1_begin, &memblock[0], sizeof(R1_begin));


?


All times are GMT. The time now is 09:04 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.