Write objects to file

Apr 23, 2020 at 9:41pm
Hi, I am trying write object to file(for example text file). I found command like
file.write((char*)&b,sizeof(b)); but in my file I have only rubbish and garbage

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
 #include <iostream>
#include <string>
#include <fstream>

using namespace std;
class Person
 {
   private:
       string name;
       int age; 
   public:
    void  show()
         {
          cout<<name<<endl;
          cout<<age<<endl;

         }
    void  GetData()
       {  
          cout<<"Input name: "<<endl;
          cin>>name;
          cout<<"Input ageL "<<endl;
          cin>>age;

       }


};
int main()
{
Person a;
Person b;

a.GetData();
b.GetData();

ofstream file;
file.open("File.txt",ios::out);
if(!file)
    {
      cout<<"Error in creating file.."<<endl;
      return 0;
    }
 file.write((char*)&a,sizeof(a));
 file.write((char*)&b,sizeof(b));

file.close();
    return 0;
}
Last edited on Apr 23, 2020 at 9:46pm
Apr 23, 2020 at 9:57pm
Rubbish!

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 <string>
#include <fstream>

using namespace std;
class Person
{
private:
	string name;
	int age;
public:
	void  show()
	{
		cout << name << endl;
		cout << age << endl;

	}
	void  GetData()
	{
		cout << "Input name: " << endl;
		cin >> name;
		cout << "Input ageL " << endl;
		cin >> age;

	}

	std::string getName()
	{
		return name;
	}

	int getAge()
	{
		return age;
	}

};
int main()
{
	Person a;
	Person b;

	a.GetData();
	b.GetData();

	ofstream file;
	file.open("File.txt", ios::out);
	if (!file)
	{
		cout << "Error in creating file.." << endl;
		return 0;
	}
	file << a.getName() << '\n' << a.getAge() << '\n';
	file << b.getName() << '\n' << b.getAge();

	file.close();
	return 0;
}


I assume you want something more like that.

EDIT:

I'm not too sure, but the "write" command seems more C style - I'd recommend just avoiding that all together. The less you have to deal with specific sizes and types, the better. Especially avoid it since it seems to want to take in a char array.

The real issue with what you were trying is that you tried to turn the whole object into a char[], and not just the string the object contains.
Last edited on Apr 23, 2020 at 10:22pm
Apr 24, 2020 at 10:38am
Hello asxxx,

Building off what zapshe has said.

For both of you. The ".read()" and .write()" functions are C++ functions, but used for binary files. You do not need that yet or want to go that direction right now.

In "main":
1
2
3
ofstream file;

file.open("File.txt", ios::out);

Line 1 is defined as an "ofstream". As the "o" implies it is already set as an output stream, so in line 3 the "ios::out" is not needed.

Save the "ios::in" and "ios::out" for a stream defined as a "fstream". There you have to tell it if it is for input, output or both.

An alternative to opening the file is: ofstream file("File.txt"); Not only does this construct an object, but the ctor will open the file at the same time.

zapshe's example of writing to the file will work. You may want to consider making a function for the class to write to the file. Then all you need is to pass the file stream to the function. This way you do not need to use the "get" functions to access the private variables.

I have a thought to consider.
1
2
3
4
5
6
7
8
void  GetData()
{
	cout << "Input name: " << endl;
	cin >> name;

	cout << "Input ageL " << endl;
	cin >> age;
}

Line 4 is formatted input. This means it will stop at a white space or "\n" whichever comes first. Leaving anything that is left for the next input. Now for cin >> age; it expects a number to be entered and it expects that number to be an "int. If the first character is not an "int" it will cause "cin" to fail and be unusable until you fix it. This is also true if you were to enter".1234". Had "age" been defined as a "double" this would work.

This would work better for your input.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void  GetData(std::string prompt)
{
	std::cout << "\n " << prompt << '\n';

	cout << "Input name: ";  // <--- Removed the 'endl". Puts the input on the same line.
	std::getline(std::cin, name);

	cout << "Input age: ";

	while (!(cin >> age))
	{
		std::cout << "\n    Invalid input! Must be a number\n";

		std::cin.clear();
		std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // <--- Requires header file <limits>.

		cout << "Input age: " << endl;
	}

	std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // <--- Requires header file <limits>.
				                                            //  Clears the input buffer before the next getline.
}

I added some things that yo may not have thought of or learned yet. At some point you will learn that about half the code is dealing with problems or potential problems from user input.

To use this the function call is:
1
2
a.GetData("  First Name");
b.GetData("  Second name");

You can adjust the string to anything that you want.

Your screen will look like this:

   First Name
Input name: Bob Smithe
Input age: 50

   Second name
Input name: Jane Doe
Input age: 40



After that you can use what zapshe has suggested or write an output function for the class. Your choice.

Andy

Edit:: formatting
Last edited on Apr 24, 2020 at 10:44am
May 6, 2020 at 5:07pm
Thank you!
Topic archived. No new replies allowed.