Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   strange read in of binary file (http://www.velocityreviews.com/forums/t609978-strange-read-in-of-binary-file.html)

zl2k 04-11-2008 06:37 PM

strange read in of binary file
 
hi, there

I have a appendable binary file of complex data structure named
data.bin created by myself. It is written in the following format:

number of Data, Data array

Suppose I have following data.bin (3 Data appended to 2 Data):

2, data0, data1, 3, data0, data1, data2

When I read and display it, I always get the following output:

2
data0
data1
3
data0
data1
data2
3
data with default value
data with default value
data with default value

Why I get an extra data set with default values have the same number
of Data as the previous valid one? Here is the read in code:

---------------------
ifstream myfile2;
myfile2.seekg(0);
myfile2.open ("data.bin", ios::in | ios::binary);
int *num2;
while (myfile2.good()){
myfile2.read((char*)num2, sizeof(int));
cout<<*num2<<" "<<endl;
Data *dataArray2 = new Data[*num2];
myfile2.read ((char*)dataArray2, sizeof (Data) * *num2);
//print dataArray2 content
delete [] dataArray2;
}
myfile2.close();
---------------------

Please help!

zl2k

zl2k 04-11-2008 08:19 PM

Re: strange read in of binary file
 
On Apr 11, 3:45 pm, "Victor Bazarov" <v.Abaza...@comAcast.net> wrote:
> zl2k wrote:
> > I have a appendable binary file of complex data structure named
> > data.bin created by myself. It is written in the following format:

>
> > number of Data, Data array

>
> > Suppose I have following data.bin (3 Data appended to 2 Data):

>
> > 2, data0, data1, 3, data0, data1, data2

>
> > When I read and display it, I always get the following output:

>
> > 2
> > data0
> > data1
> > 3
> > data0
> > data1
> > data2
> > 3
> > data with default value
> > data with default value
> > data with default value

>
> > Why I get an extra data set with default values have the same number
> > of Data as the previous valid one? Here is the read in code:

>
> > ---------------------
> > ifstream myfile2;
> > myfile2.seekg(0);
> > myfile2.open ("data.bin", ios::in | ios::binary);
> > int *num2;
> > while (myfile2.good()){
> > myfile2.read((char*)num2, sizeof(int));
> > cout<<*num2<<" "<<endl;
> > Data *dataArray2 = new Data[*num2];
> > myfile2.read ((char*)dataArray2, sizeof (Data) * *num2);
> > //print dataArray2 content
> > delete [] dataArray2;
> > }
> > myfile2.close();
> > ---------------------

>
> > Please help!

>
> Common mistake. First, you never check the result of your read
> operations. Change your code to behave appropriately if the file
> cannot be read (where you read your 'num2'): do you really want
> to keep reading the stream if the first read fails? Second, I
> strongly recommend reading the archives on file streams, 'read',
> formatted (or unformatted) I/O, etc. BTW, what book are you
> reading that doesn't explain how to handle input that can run
> out of information (eof conditions)?
>
> V
> --
> Please remove capital 'A's when replying by e-mail
> I do not respond to top-posted replies, please don't ask


I tried while (!myfile2.eof()){} but makes no difference. How can I
fix it? I know my code did not stop when reached the end of the file.
zl2k

zl2k 04-11-2008 09:32 PM

Re: strange read in of binary file
 
On Apr 11, 4:40 pm, "Victor Bazarov" <v.Abaza...@comAcast.net> wrote:
> zl2k wrote:
> > On Apr 11, 3:45 pm, "Victor Bazarov" <v.Abaza...@comAcast.net> wrote:
> >> zl2k wrote:
> >>> I have a appendable binary file of complex data structure named
> >>> data.bin created by myself. It is written in the following format:

>
> >>> number of Data, Data array

>
> >>> Suppose I have following data.bin (3 Data appended to 2 Data):

>
> >>> 2, data0, data1, 3, data0, data1, data2

>
> >>> When I read and display it, I always get the following output:

>
> >>> 2
> >>> data0
> >>> data1
> >>> 3
> >>> data0
> >>> data1
> >>> data2
> >>> 3
> >>> data with default value
> >>> data with default value
> >>> data with default value

>
> >>> Why I get an extra data set with default values have the same number
> >>> of Data as the previous valid one? Here is the read in code:

>
> >>> ---------------------
> >>> ifstream myfile2;
> >>> myfile2.seekg(0);
> >>> myfile2.open ("data.bin", ios::in | ios::binary);
> >>> int *num2;
> >>> while (myfile2.good()){
> >>> myfile2.read((char*)num2, sizeof(int));
> >>> cout<<*num2<<" "<<endl;
> >>> Data *dataArray2 = new Data[*num2];
> >>> myfile2.read ((char*)dataArray2, sizeof (Data) * *num2);
> >>> //print dataArray2 content
> >>> delete [] dataArray2;
> >>> }
> >>> myfile2.close();
> >>> ---------------------

>
> >>> Please help!

>
> >> Common mistake. First, you never check the result of your read
> >> operations. Change your code to behave appropriately if the file
> >> cannot be read (where you read your 'num2'): do you really want
> >> to keep reading the stream if the first read fails? Second, I
> >> strongly recommend reading the archives on file streams, 'read',
> >> formatted (or unformatted) I/O, etc. BTW, what book are you
> >> reading that doesn't explain how to handle input that can run
> >> out of information (eof conditions)?

>
> >> V
> >> --
> >> Please remove capital 'A's when replying by e-mail
> >> I do not respond to top-posted replies, please don't ask

>
> > I tried while (!myfile2.eof()){} but makes no difference. How can I
> > fix it? I know my code did not stop when reached the end of the file.
> > zl2k

>
> Look at what 'read' returns. You can also check the condition of the
> stream right after 'read' to see whether the stream is "good". You
> can check for 'eof' instead of "good" after 'read'...
>
> I don't want to write your program for you. Trust me, you'll be much
> better off if you research this stuff yourself.
>
> V
> --
> Please remove capital 'A's when replying by e-mail
> I do not respond to top-posted replies, please don't ask


Thanks, I can jump out off the loop by checking the good() or eof()
after myfile2.read((char*)num2, sizeof(int));
So I can move one. Have good weekend.
zl2k

James Kanze 04-12-2008 08:41 AM

Re: strange read in of binary file
 
On 11 avr, 20:37, zl2k <kdsfin...@gmail.com> wrote:

> I have a appendable binary file of complex data structure
> named data.bin created by myself. It is written in the
> following format:


> number of Data, Data array


Which doesn't begin to tell me anything about the format, at
least if it is binary. You have to specify the format of the
various types.

> Suppose I have following data.bin (3 Data appended to 2 Data):


> 2, data0, data1, 3, data0, data1, data2


OK, but that's text.

> When I read and display it, I always get the following output:


> 2
> data0
> data1
> 3
> data0
> data1
> data2
> 3
> data with default value
> data with default value
> data with default value


> Why I get an extra data set with default values have the same number
> of Data as the previous valid one?


The simple answer is that you've got so much undefined behavior
in your code that we can't say anything about it. In practice,
I find it hard to believe that the code didn't crash.

> Here is the read in code:


> ---------------------
> ifstream myfile2;
> myfile2.seekg(0);


You can't seek on an unopened file. This should fail.
According to the current standard, that means that all following
operations should also fail (but I think a lot of
implementations do reset the failbit on open, which is logical,
and will be what the next version of the standard requires, I
think).

> myfile2.open ("data.bin", ios::in | ios::binary);


Of course, you really should check that the open succeeded.

> int *num2;


Which points where? Avoid uninitialized variables, especially
if they're pointers.

> while (myfile2.good()){


Classical error. At this point, good() doesn't tell you
anything. (The standards committee would do well to deprecate
the function. I've never found a use for it.)

What you want is:

while ( myfile.someInput... ) {

> myfile2.read((char*)num2, sizeof(int));


And bang. You pass an uninitialized pointer to istream::read().
istream::read() isn't going to like that. Formally, it's
undefined behavior, and no matter what the compiler and the
library do after is correct. In a good implementation, unless
you've turned off all debugging and turned on all optimization,
it should crash the program.

> cout<<*num2<<" "<<endl;


Did the above read succeed? Who knows?

> Data *dataArray2 = new Data[*num2];
> myfile2.read ((char*)dataArray2, sizeof (Data) * *num2);
> //print dataArray2 content
> delete [] dataArray2;
> }
> myfile2.close();
> ---------------------


More information is needed. Like the actual format of the file.
But the basic structure of the program should be something like:

std::ifstream file( name, ios::in | ios::binary ) ;
if ( ! file ) {
// error, could not open...
} else {
readData( file ) ;
}

with

void
readData( std::istream& source )
{
int count ;
if ( ! getInt( source, count ) ) {
// error...
} else {
while ( someInput ) {
// process input...
}
}
}

Reading and writing binary data requires some understanding of
what you're doing, though. (Reading and writing text requires
even more, but that's mostly been done for you.) I'd avoid it
if at all possible.

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

James Kanze 04-12-2008 08:47 AM

Re: strange read in of binary file
 
On 11 avr, 23:32, zl2k <kdsfin...@gmail.com> wrote:
> On Apr 11, 4:40 pm, "Victor Bazarov" <v.Abaza...@comAcast.net> wrote:


> Thanks, I can jump out off the loop by checking the good() or eof()
> after myfile2.read((char*)num2, sizeof(int));


As Victor said, research. Even a little research should reveal
that good() is always the wrong function, and eof() is only
really valid after you know that the input has failed.

I think what Victor was getting at is that you should start by
learning the error model used in iostream, and what the various
state functions actually return. Their names are misleading, to
put it mildly, and there is actually some ambiguity with regards
to eof(), but there are standard idioms that are well
documented, and that work.

He also mentionned that you should research binary input, and
how to implement binary formats. It's a non-trivial subject, to
put it mildly, and best avoided until you understand some of the
low level details of binary representation.

And while he didn't mention it, I think you really have to learn
at least a little about the C++ memory model, and what
declarations mean, before you can even consider going further.
Just defining a pointer doesn't create anything which it might
point to, for example.

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34



All times are GMT. The time now is 05:59 AM.

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