Transfering data from class

Hello,
I have beginner problem which cant solve for few days.
Basically, I understand that I don't understand to work with pointers :)
My program declare class for data, fill data, write data to file, then read data from file and show readed data.
In single file single function (main) this works but I can't get program to work
when read/write function is in separate cpp file.
Please help to get my example program working.

Situation is:
header bClass.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#ifndef BCLASS_H
#define BCLASS_H
//<cstring> must be declared before bClass.h

class MyClass
{
public:
	char   FullName[40];                //40
	char   CompleteAddress[120];        //120
	char   Gender;                      //1
	double Age;                         //8
	bool   myBool;                      //1
                                        //---
                                        //170
};
int RWrecord (bool RW, long record, MyClass *two);

//-------- Global variables ----------
//
// I NEED FILENAME TO BE PUBLIC
// BUT THIS DONT WORK
// COMPILER SAYS FILENAME ALREADY DECLARED

//std::string filename="myJunk.dat";

#endif 


bClass.cpp (file with function)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <fstream>
#include <iostream>
#include <cstring>
//---------------------
#include "bClass.h"
//---------------------

int RWrecord (bool RW, long record, MyClass *two)
{
 std::string filename="myJunk.dat";
 if (RW) //read or write = false or true
    {
        std::ifstream ifs(filename.c_str(), std::ios::binary);
        //seek to start byte of desired record
        ifs.seekg (sizeof(two)*record, std::ios::beg);
        //read data in size of class
        ifs.read((char*)&two, sizeof(two));
        ifs.close();
    }
    else
    {
        std::ofstream ofs(filename.c_str(), std::ios::binary);
        ofs.seekp (sizeof(two)*record, std::ios::beg);
        ofs.write((char*)&two, sizeof(two));
        ofs.close();
    }
    return 0;
}


Main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <iostream>
#include <cstring>
//---------------------
#include "bClass.h"
//---------------------

int main()
{
 // I would like filename to be global
	std::string filename = "myJunk.dat";
	//remove(filename.c_str());

    //declarations
    bool RW;
    long record;
	MyClass one;

	//assign data
	std::strcpy(one.FullName, "Row two");
	std::strcpy(one.CompleteAddress, "My row two adress");
	one.Gender = 'M';
	one.Age = 3.14;
	one.myBool = true;

    record = 2;
    RW = true;   //true=write

    //call to write assigned data from class to file
    int RWrecord (bool RW, long record, MyClass *one);

//-------------------------------------------------------------------

    //same record
    record = 2;
    RW = false;  //false=read
    //class to new variable
    MyClass three;
    //all to read from file and assign data from file to class
    int RWrecord (bool RW, long record, MyClass *three);

    //show data
	std::cout << "My Information\n";
	std::cout << "My Name: " << three.FullName << std::endl;
	std::cout << "Address:      " << three.CompleteAddress << std::endl;

	if(three.Gender == 'f' || three.Gender == 'F')
		std::cout << "Gender:       Female" << std::endl;
	else if(three.Gender == 'm' || three.Gender == 'M')
		std::cout << "Gender:       Male" << std::endl;
	else
    std::cout << "Gender:       Unknown" << std::endl;
    std::cout << "Age:          " << three.Age << std::endl;
//-----------------------------------------------------------------------
    std::cout << "Size:          " << sizeof(three) << std::endl;
    // sizeof(three) is reported 184 instead of 170
    // HOW THAT CAN BE?
	return 0;
}
There are a fair few things wrong:


Let's start with these:


1. Main.cpp
Lines 26 and 35 - your comments say true=write and false=read - but if
you recheck your int RWrecord (bool RW, long record, MyClass *two)
function in bclass.cpp - you will see that is written the other way around (read on true , write on false).

2. bclass.cpp
Lines 17 : ifs.read((char*)&two, sizeof(two)); and 24: ofs.write((char*)&two, sizeof(two));
Pointer problems - (char*)&two should be (char*) two
(although it would be preferable to use c++ style casting)

3. main.cpp
Lines 29 and 39 - int RWrecord (bool RW, long record, MyClass *one); - this is not the correct way to call a function

4. main.cpp
Line 55 - your comments
1
2
    // sizeof(three) is reported 184 instead of 170
    // HOW THAT CAN BE? 
-
The sizeof() gives the correct size for a particular type - You shouldn't add up the size of
the individual members of a class by youself and assume that is the size of
an object.
Structures and classes can have hodden paddingbytes to align the members for efficient access, and
may also have hidden members (like virtual function table pointers).

Last edited on
Hello guestgulkan, thanks for reply,
I apply your remarks but my program still dont work.
It is really confusing to learn a new language so concrete help may be most useful to learn.
Error with bool can make only a full :)

Here it seems that my program dont even go through RWrecord function.
I think that because I havent created data file in current directory what should be.
How to call actual function correctly?

I try to get sizeof every element and this size is "as expected".
How then to get size of object in particular case (170 bytes) or size of struct in c++?
like i said - those problems are ones i noticed straight away.
They are other errors ( I just noticed another pinter related issue in the RWrecord function).
Also, if the file is empy to start with, you cannot save a record at position 2 in the file - as this will be the only record in the file - which means you cannot reload it from position 2 because the file has only one record in it. See what I mean??



in your code - sizeof(three) gives the size of the three object which an object of MyClass
so sizeof(three) and sizeof(MyClass) should give the same result

**I repeat - what sizeof() reports as the size of an object (for example the size of a structure) is CORRECT -- any value that you calculate by adding up the individual sizes of the members
of that structure is WRONG if it differs from the sizeof value.***

So you mayhave got the size of every element and the size is is 'as expected' - but as you have
found, the overall size of the structure is bigger.
re-read my first post about compilers padding out structures for efficieny reasons.

If you want the structure to be an exact fit to the members - you will have to use
a compiler_specific option on the structure ( a pragma directive if you are using microsoft visual C++)

This explains it:
http://en.wikipedia.org/wiki/Sizeof

if you scroll down to the end you will see - structure padding

Last edited on
I might as well mention -
it is best not to read data directly onto a class object - sooner or later you will run into trouble.
Last edited on
Well, I was hoping in more conrete help but I will study all what you mentioned.

Maybe you dont work much with this kind of stuff but as I say, this example works well when I have RW function incorporated in my main. That means that binary files opened in this mode automatically CREATES file and you can write data anywhere you want. Fe. on "record" 12345. That mean you will have filesize (12345*170 bytes). I work with structures and binary files wery successfull in VB and I know much about that.
My only problem is to get same functionality with c++ which I try to learn.
Topic archived. No new replies allowed.