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:
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
|