Unable to read object form file

Unable to read object from file when using std::string or char *

but i really have to use any of them, is there any way that it will works?

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

using namespace std;
 
class student
{
    private:
        const char* name = "";
		int age = 14;
    public:
		student()
		{
			std::string test = "DSAda";
			name = test.c_str();
		}
        void showData(void)
        {
        cout<<"Name:"<<name<<",Age:"<<age<<endl;
        }
};
int main()
{
    student s;
     
    ofstream file;
 
    //open file in write mode
    file.open("data.img",ios::app);
    if(!file)
    {
      cout<<"Error in creating file.."<<endl;
      return 0;
    }
    cout<<"\nFile created successfully."<<endl;
     file.write((char*)&s,sizeof(s));   
 
    file.close(); 
    cout<<"\nFile saved and closed succesfully."<<endl;
 
    ifstream file1;
    file1.open("data.img",ios::in);
    if(!file1){
        cout<<"Error in opening file..";
        return 0;
    }
    
    while (!file1.eof()) {
    file1.read((char*)&s,sizeof(s));

    s.showData();
    }

    file1.close();
     
    return 0;
}


it gives me Segmentation fault error
Thanks.
Last edited on
Instead of read and write, why not use fstream operator<< and operator>>

https://en.cppreference.com/w/cpp/io/basic_fstream/basic_fstream ?

s is an object of type student, not a string, one can't read/write from/to it directly.

Line 49 is bad form, doesn't do what you think.

It has never been a requirement to put void when there are no function parameters:

void showData(void)

Also, learn how to use a debugger :+)
Last edited on
You can't use .read/.write() with data that uses dynamic memory. You're copying the value of the pointer and not the data contents pointed to.

See this thread http://www.cplusplus.com/forum/general/278652/
Cheekily, I overloaded read() and write(). Maybe the result Is a bit nasty:

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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#include <fstream>
#include <iostream>
#include <cstring>
#include <string>

class student
{
    private:
        char* name = nullptr;
		int age = 14;
    public:
		student()
		{
			std::string test = "DSAda";
			name = new char[ test.length() + 1 ];
			std::strcpy( name, test.c_str() );
		}
		~student() { delete[] name; }

        void set_name( const char * s)
        {
            size_t sz = std::strlen( s );
            if( sz > std::strlen( name ) )
            {
                delete[] name;
                name = new char[sz+1];
            }
            std::strcpy( name, s );
        }

        void showData()
        {
            std::cout<<"Name:"<<name<<",Age:"<<age<<std::endl;
        }

        friend class my_ofstream;
        friend class my_ifstream;
};

class my_ofstream : public std::ofstream
{
public:
    std::ostream&  write( const student * s, int sz)
    {
        for( size_t i = 0; i < sz; ++i )
        {
            this->std::ofstream::write( (const char*) s[i].name, strlen(s[i].name) + 1 );
            this->std::ofstream::write( (const char*) &(s[i].age), sizeof(int) );
        }
        return *this;
    }
};

class my_ifstream : public std::ifstream
{
public:
    std::istream& read( student * s, int sz)
    {
        for( size_t i = 0; i < sz; ++i)
        {
            std::string tmp;
            while( true )
            {
                char ch;
                if (! this->get(ch) ) break;
                if( ch && ch != -1 ) tmp = tmp + ch;
                else break;
                //std::cout <<  " x::" << ch;
            }
            s[i].set_name( tmp.c_str() );

            this->std::ifstream::read( (char*) &(s[i].age), sizeof(int) );
        }
        return *this;
    }
};

int main()
{
    student s;

    my_ofstream file;

    //open file in write mode
    file.open("data.img",std::ios::app);
    if(!file)
    {
      std::cout<<"Error in creating file.."<<std::endl;
      return 0;
    }
    std::cout<<"\nFile created successfully."<<std::endl;
     file.write( &s, 1 );

    file.close();
    std::cout<<"\nFile saved and closed succesfully."<<std::endl;

    my_ifstream file1;
    file1.open("data.img",std::ios::in);
    if(!file1){
        std::cout<<"Error in opening file..";
        return 0;
    }

    while (file1.read( &s, 1) ) {
        s.showData();
    }

    file1.close();

    return 0;
}
Usually you'd overload >> and << :)
This:
1
2
3
4
5
student() {
	std::string test = "DSAda";
	name = new char[ test.length() + 1 ];
	std::strcpy( name, test.c_str() );
}

Should: probably be
1
2
3
4
student(const std::string& test = "") {
	name = new char[ test.length() + 1 ];
	std::strcpy( name, test.c_str() );
}


Not entirely happy with your streaming code.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
std::ostream& operator<<( std::ostream & os, const student & s )
{
    return os.write( (const char*) s.name, strlen(s.name) + 1 ).write( (const char*) &(s.age), sizeof(int) );
}

std::istream & operator>>( std::istream& is, student & s )
{
    std::string tmp;
    for( char c; is.get(c); )
    {
        if( c && c != is.end ) tmp += c;
        else break;
    }
    s.set_name( tmp.c_str() );
    return is.read( (char *) &(s.age), sizeof(int) );
}
Thanks you all for answers
Topic archived. No new replies allowed.