Click to See Complete Forum and Search --> : Converting buffer into data


mjan
September 23rd, 2001, 10:04 PM
Hi everybody,

This is what I am trying to do:

I have a:
struct t{
char c[10];
int i;
};

I write this to file e.g. with values c="abcd" and i=1234.

Now I read the entire data back into a buffer buf[16]. And I want to
convert this buffer back into the original data. (I am trying to do
what operating system would do automatically if I had used the same
struct to read the data back in.)

I then parse the buf for those values by copying the data character by
character into another buffer.

I am able to get the character data back.

My problem: I cannot retrieve the integer back. When I do an atoi(),
the value I get is zero.

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

struct t
{
char c[10];
int i;
};


struct v
{
char buf[16];
};

void main()
{
int x=0;

t my;
v your;

my.i=1234;
strcpy(my.c, "abcd");

cout << "size of my: " << sizeof(my) << endl;

fstream f;

f.open("test", ios::out | ios::binary); // first write data to file
f.write((char *)&my, sizeof(my));
f.close();

//now read back in
f.open("test", ios::in | ios::binary);
f.read((char *)&your, sizeof(your));
f.close();

cout << "char " << your.buf << endl;

char temp[10];

// 0 - 9 is character data
for(x=0; x<10;x++) temp[x] = '\0'; // fill in null terminators
for(x=0; x<10; x++)temp[x]=your.buf[x];

cout << "temp character part of my: " << temp << endl;

// 10-15 is integer data (??:not sure)
for(x=0; x<10;x++) temp[x] = '\0'; // fill in nulls
for(x=0; x<6; x++)temp[x]=your.buf[x+10];

cout << "temp int part of my: " << temp << endl;
cout << "atoi : " << atoi(temp) << endl; // should i get back: 1234?
// the result i get for this cout = 0
// i want the integer i originally stored = 1234
}

Thanks for all your help!

Karnak
September 24th, 2001, 05:19 PM
Hi there,

There were a few issues with your code, and a couple of things that you weren't aware of as far as how the int is written/read to/from the file. Here is working source:


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

typedef struct _t
{
char c[10];
int i;
} t;


typedef struct _v
{
char buf[16];
} v;

void main()
{
int x = 0;
t my;
v your;

my.i=1234;
strcpy(my.c, "abcd");

cout << "size of my: " << sizeof(my) << endl;

fstream f;

f.open("test", ios::out | ios::binary); // first write data to file
f.write((char *)&my, sizeof(my));
f.close();

//now read back in
f.open("test", ios::in | ios::binary);
f.read((char *)&your, sizeof(your));
f.close();

cout << "char " << your.buf << endl;

char temp[4]; // an int is 4 bytes

// 0-12 is character data. When you declare a buffer of a
// particular size, the actual size that is allocated is rounded
// up to a multiple of word size so that everything is word-aligned.
// c[10] is actually 12 bytes (3 * wordsize).

for(x = 0; x < 4; x++)
{
temp[x] = your.buf[x+12];
}

// atoi converts a string from "1234" to the num 1234.
// but we dont have the string "1234" we have the value
// 1234 stored in bytes in the string... so we need to manually
// convert:

int num = 0;

num += (unsigned char)temp[0];
num += (unsigned char)temp[1] << 8;
num += (unsigned char)temp[2] << 16;
num += (unsigned char)temp[3] << 24;

cout << "num = " << num << endl;
}




If you don't understand what's going on here, mail me privately and I'll give more detail.
good luck
K.

If you can't be good, be good at it!