PDA

View Full Version : How to read/write sets of orderded numbers in binary



kaydknight
9th March 2007, 04:40
Hello, I would like to ask a question.

Does anyone know how to effectively store a 2d array of numbers in binary file, and then able to read them later into array.

For example, This are the samples of numbers I need to write:

x1 x2 x3
y1 1 1 1
y2 2 2 3
y3 3 3 5
y4 4 5 6
y5 5 6 8

If in ascii, I can write like this:
1 1 1
2 2 2
3 3 5
...
5 6 8

But how about writing it into binary file?
When reading, How do I know when I reached end-of-row for one column and store next number on column+1 (since binary files are ordered sequentially).
I've been thinking of putting some kind of byte signal to indicate I reached end-of-row, but I don't have the idea how.
Also, I predict a problem, where later, my sets of number will be non-uniformed (1 col have 5 rows, next col have 9 rows and so on).

Can anyone give a simple example how to write it? I'm comfortable with using QDataStream and iostreams binary mode, but I think this is more a problem of the design of it.

E.g : After reading the binary file, I want to store them into array.
array[0,0] = 1
... and so on until
array[2,4] = 8

Thanks in advance! I've tried googling, but they only tell me the basics of binary read/write.

e8johan
9th March 2007, 07:01
The easiest would be to store the dimensions to expect first, for example, this matrix:

1 1 1
2 2 2
3 3 3

Would be stored as

3 3 1 1 1 2 2 2 3 3 3

Where the first two threes would indicate that we're dealing with a 3x3 matrix. Then the data follow. Using an index, starting at 0 for the first one, then increasing you can find your matrix coordinate like this:

row = index/width; // Integer division, always rounds down
col = index%width; // Modulus

The final check would be to ensure that the index == width*height when you have reached the end of the file.

Also, when storing binary data using Qt, make sure to set your QDataStream version using myDataStreamObject->setVersion( xxx ); to ensure compatibility between Qt versions.

kaydknight
10th March 2007, 18:57
Oh, what a solution! Thanks a lot for this! I'm baffled on how I can't come up with such a cheap (meaning not computing expensive) solution. I guess this seperates programmers, those who can program, and those who can design software.

As I said, I originally tried to represent a byte as end of row. Well to do it, I must check every designated byte for it, using for and if loops, that would have really slow down computing time.

Emm.. just a general question then, is this how people code for binary data, by inputting the sizes of particular row/col first? Are there any other types out there? I'm curious on the designs of binary read/write people can come up with.

vermarajeev
12th March 2007, 06:50
The easiest would be to store the dimensions to expect first, for example, this matrix:

1 1 1
2 2 2
3 3 3

Would be stored as

3 3 1 1 1 2 2 2 3 3 3

Where the first two threes would indicate that we're dealing with a 3x3 matrix. Then the data follow. Using an index, starting at 0 for the first one, then increasing you can find your matrix coordinate like this:

row = index/width; // Integer division, always rounds down
col = index%width; // Modulus

The final check would be to ensure that the index == width*height when you have reached the end of the file.

Also, when storing binary data using Qt, make sure to set your QDataStream version using myDataStreamObject->setVersion( xxx ); to ensure compatibility between Qt versions.

Hi e8johan,
I have written a sample program about what you have told in above post. Please correct me if I'm wrong...


#include <iostream>
#include <fstream>
using namespace std;

int main()
{
int arr[3][3] = { 1, 1, 1,
2, 2, 2,
3, 3, 3 };


ofstream ofs("test.txt", ios::binary);
const char* data = "33111222333";
string line = data;
ofs.write( line.data(), line.length() );
ofs.close();

char buffer[256];
ifstream ifs("test.txt", ios::binary);
ifs.getline(buffer, sizeof(buffer) );
ifs.close();

string bufferdata = buffer;

int width = bufferdata.at(0) - '0';
int height = bufferdata.at(1) - '0';

int index = 0;
int row = 0, col = 0;

while(1)
{
if( index == width*height )
break;

row = index/width; // Integer division, always rounds down
col = index%width; // Modulus

cout<<"Row:"<<row<<" "<<"Col:"<<col<<endl;
bufferdata.at(index++);
}
return 0;
}