Pregunta

I have created a simple program which writes an object to a file and then reads back whats written to the file. My problem is when i write to the file unwanted values get written to the file and when i retrieve back the data , those values also get retrieved , which i don't want.

Here is what i have done :

File Handling Implementation

//File Handling class Implementation
File::File(){}

string File::writeObject(Person obj)
{
    ofstream outFile("myFile.txt", ios::out);

    if( !outFile ) {
        cout << "No File" << endl;
    }

    outFile.write( reinterpret_cast<const char *> (&obj), sizeof(obj) );
    return "Done";
}

Person.H:

//Person.H
class Person {
    private: string name;
    public: Person();
    public: void setName(string name);
    public: string getName();   
};

Main Implementation : using namespace std;

int main( int argc, char* argv[] )
{
    Person p1;
    p1.setName("Shehan");

    File f1;

    cout << f1.writeObject(p1) << endl; //writes to the file

    ifstream readFile("myfile.txt",ios::in); creates object to read from file

    string name; // creates variable to hold the value
    readFile >> name; reads from file

    cout << name << endl; //prints the value
    system("pause");

    return 0;
}

I think only "shehan" should be written to the file but what's written to the file is:

0ÂÒ Shehan ÌÌÌÌÌ'þ¨

When i read again :

enter image description here

What seems to be the problem here?

¿Fue útil?

Solución

What is going on here is that you aren't formatting the output. All output must be formatted in some way, in order to ensure that you can reread it; just copying the bit pattern from memory is useless.

The usual way of handling this would be to define an operator << (and an operator >>, in order to read) for your class. This operator will output all of the individual elements of the class, with appropriate separators so that you can determine where one ends and the next begins when you read. If, for example, we take a simple example:

class Person
{
    std::string name;
    int age;
public:
    //  ...
    friend std::ostream& operator<<( std::ostream& dest, Person const& obj )
    {
        dest << '"' << name << '"' << age;
        return dest;
    }

    friend std::istream& operator>>( std::istream& source, Person& obj )
    {
        char ch;
        source >> ch;
        if ( ch != '"' ) {
            source.setstate( std::ios_base::failbit );
        }
        std::string name;
        while ( source.get( ch ) && ch != '"' ) {
            name += ch;
        }
        if ( ch != '"' ) {
            source.setstate( std::ios_base::failbit );
        }
        int age;
        source >> age;
        if ( source ) {
            obj = Person( name, age );
        }
        return source;
    }
};

You'll notice that input is a lot more difficult than output. When outputting, you know what you've got (because of the C++ type system, and your own verification of class invariants). When inputting, you never know what the user is going to give you, so you have to check for all possibilities. (You might, for example, want to forbid additional characters like a '\n' in the name. Just add them to the test in the while.)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top