Generalize function to read different structure from file

N

Nash

Hi,
I have two different files which is filled with data from two
different structures like

struct student
{
char* name;
int age;
};

which is stored in student.dat file and another structure

struct staff
{
char *name,
int age;
int exp;
};

which is stored in staff.dat file. I have to write a function which
should read the first 20 data and write it into sepearate file. I
thought of generalizing the function so i had a function like
enum DATA
{
STUDENT,
STAFF
};
ReadWriteData(void *pData,DATA enData)
{
void * pTempStructArray;
if (enData == STUDENT)
{
pTempStructArray= new student[20];
iSizeOfStruct = sizeof(student);
}
else
{
pTempStructArray= new staff[20];
iSizeOfStruct = sizeof(staff);
}

ReadFile(hFile, &pTempStructArray [0], iSizeOfStruct,
&NumBytesReadWritten, NULL);
}

but the problem is if i try to read the data into this void pointer it
is giving some error like "error C2036: 'void *' : unknown size". Any
idea to generalize this function so that i can used the same function
to copy both the data.
 
S

Stuart Redmann

Nash said:
Hi,
I have two different files which is filled with data from two
different structures like

struct student
{
char* name;
int age;
};

which is stored in student.dat file and another structure

struct staff
{
char *name,
int age;
int exp;
};

which is stored in staff.dat file. I have to write a function which
should read the first 20 data and write it into sepearate file. I
thought of generalizing the function so i had a function like
enum DATA
{
STUDENT,
STAFF
};
ReadWriteData(void *pData,DATA enData)
{
void * pTempStructArray;
if (enData == STUDENT)
{
pTempStructArray= new student[20];
iSizeOfStruct = sizeof(student);
}
else
{
pTempStructArray= new staff[20];
iSizeOfStruct = sizeof(staff);
}

ReadFile(hFile, &pTempStructArray [0], iSizeOfStruct,
&NumBytesReadWritten, NULL);
}

but the problem is if i try to read the data into this void pointer it
is giving some error like "error C2036: 'void *' : unknown size". Any
idea to generalize this function so that i can used the same function
to copy both the data.

The problems of this piece of code are so many that its hard to find a place to
start with. So lets just analyze what you have coded so far:
The compiler complains that it cannot evaluate the expression
"&pTempStructArray [0]"
of the statement
ReadFile(hFile, &pTempStructArray [0], ...

If examine this parameter really closely you'll find that pTempStructArray[0] is
the trouble-maker: You want to access the first element of this array. As
pTempStructArray is defined as void*, the compiler doesn't know the type of the
pointer (it knows that it is a pointer, but it doesn't know anything about the
data that is pointed to).

Thus you cannot use any pointer arithmetic on this pointer (bear in mind that
pTempStructArray[0] is in this case the same as pTempStructArray + 0). The
reason for this is that if you have a pointer "p" to some type "T", the
expression "p[number]" denotes the memory location &p plus number times the size
of T in bytes. In your case you give the compiler no information about the type
pointed to (the compiler cannot take the size of void).

You could argue that the first element of an array has the same address as the
array itself, so the compiler wouldn't need to know the size of the type pointed
to in this particular case. Although the compiler _could_ generate proper code
for this, the C++ standard certainly allows it to issue an error.

To get your code compiled you can simply pass the address of the array in the
call to ReadFile:
ReadFile(hFile, pTempStructArray, ...
will do just fine.

Having done this, you'll quickly find out about the other errors of your
programme, but this is a story for a different posting.

Regards,
Stuart
 
N

Nash

Hi Stuart,
Thanks for your quick response. The crux of the posting is to get
different ideas for implementing the solution to the problem. If the
compiler will not allow me to read the file using void * thats ok. Is
there any way to actually implement this functionality??

Thanks in advance.
 
S

santosh

Hi Stuart,
Thanks for your quick response.

Please quote the relevant portions of the message to which you're
replying. There are times when previous articles are not available on
an Usenet server, for whatever reason.
The crux of the posting is to get
different ideas for implementing the solution to the problem. If the
compiler will not allow me to read the file using void * thats ok. Is
there any way to actually implement this functionality??

At some point in the program there has to be some separate logic for
each type of data. If needed you can abstract the function that reads
the files containing the struct objects into memory. However when you
need to perform some operation on the data you need to know the type.

Generic I/O functions like fread() and fwrite() can read any type of
data. You can write functions to call them in an appropriate manner to
read the different types of data. Or you can read the data to an array
of unsigned char. But in the latter case you need to know the type if
you want to perform most operations on the data portably.
 
B

benben

[snip]
which is stored in staff.dat file. I have to write a function which
should read the first 20 data and write it into sepearate file. I
thought of generalizing the function so i had a function like
enum DATA
{
STUDENT,
STAFF
};
ReadWriteData(void *pData,DATA enData)
{
void * pTempStructArray;
if (enData == STUDENT)
{
pTempStructArray= new student[20];
iSizeOfStruct = sizeof(student);
}
else
{
pTempStructArray= new staff[20];
iSizeOfStruct = sizeof(staff);
}

ReadFile(hFile, &pTempStructArray [0], iSizeOfStruct,
&NumBytesReadWritten, NULL);
}

Generalization often comes after specialization. That is, before you
start to write the above generalized function, you may consider writing:

void ReadWriteStudentData(...);
void ReadWriteStaffData(...);

So a generalized solution can be composed using the above:

void ReadWriteData(Data enData)
{
if (enData == STUDENT)
return ReadWriteStudentData(...);

if (enData == STAFF)
return ReadWriteStaffData(...);
}
 
S

Stuart Redmann

Nash said:
Hi Stuart,
Thanks for your quick response. The crux of the posting is to get
different ideas for implementing the solution to the problem. If the
compiler will not allow me to read the file using void * thats ok. Is
there any way to actually implement this functionality??

There may a bit of an misunderstanding there: The compiler won't disallow you to
read the contents of the file using a void* pointer. It disallows to use the
expression &pTempStructArray [0]. Replace the following line

ReadFile(hFile, &pTempStructArray [0], iSizeOfStruct,
&NumBytesReadWritten, NULL);

by

ReadFile(hFile, pTempStructArray, iSizeOfStruct,
&NumBytesReadWritten, NULL);

and the compiler will happily compile it (if you fix the other syntactical
errors in the code you have posted). Keep in mind that the programme contains
several semantical errors (the code does not do what you think it is doing).
Before you get to debug these, you'll have to get the code compiled, though.

Regards,
Stuart
 
N

Nash

Nash said:
Hi Stuart,
Thanks for your quick response. The crux of the posting is to get
different ideas for implementing the solution to the problem. If the
compiler will not allow me to read the file using void * thats ok. Is
there any way to actually implement this functionality??

There may a bit of an misunderstanding there: The compiler won't disallow you to
read the contents of the file using a void* pointer. It disallows to use the
expression &pTempStructArray [0]. Replace the following line

ReadFile(hFile, &pTempStructArray [0], iSizeOfStruct,
&NumBytesReadWritten, NULL);

by

ReadFile(hFile, pTempStructArray, iSizeOfStruct,
&NumBytesReadWritten, NULL);

and the compiler will happily compile it (if you fix the other syntactical
errors in the code you have posted). Keep in mind that the programme contains
several semantical errors (the code does not do what you think it is doing).
Before you get to debug these, you'll have to get the code compiled, though.

Regards,
Stuart

thanks stuart for your help. i know that my code will give compilation
error i will fix it and let you know whether it is working.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,825
Latest member
VernonQuy6

Latest Threads

Top