Search code examples
c++ifstream

c++ ifstream cant read string, and getting error when read char


I have this code that writes to a file:

cout << "titre = ";
cin >> livre.titre;
cout << "isbn = ";
cin >> livre.isbn;
cout << "auteur = ";
cin >> livre.auteur;
cout << "annee = ";
cin >> livre.annee;
cout << "editeur = ";
cin >> livre.editeur;
cout << "prix = ";
cin >> livre.prix;
cout<<"===================="<<endl;

ofstream write("livres",ios::app);
write.write (( char *)&livre, sizeof livre );
write.close ();}

and this one to read from the file:

 void affiche ()
 {
    livres livre;
    ifstream read ("livres");
    read.read (( char *)&livre,sizeof livre);
    while (read)
    {
        cout << "num : " << livre.num
             << "  | isbn : " << livre.isbn
             << "  | titre : " << livre.titre
             << "  | auteur : " << livre.auteur
             << "  | editeur : " << livre.editeur
             << "  | annee : " << livre.annee
             << "  | prix : " << livre.prix
             << endl;
        read.read (( char *)&livre, sizeof livre);
    }
    read.close ();
}

Now, if I define the variables as char as in:

char titre[3];
char auteur[3];
char editeur[3];

The first cout would output all the 3 chars. For example, if I fill titre with 'abc' and auteur with 'def' and editeur with 'ghi'; the output I get from cout for titre is abcdefghi, the output from cout for auteur is defghi, and the output for editeur is ghi. The problem doesn't occur if I define my three variables as ints. And when I change these variables to string, the compiler works well, but the exe sticks in the first string cout.

Here's the full code:

class livres{
public:
void creer () {
    cout << "titre = ";
    cin >> livre.titre;
    cout << "isbn = ";
    cin >> livre.isbn;
    cout << "auteur = ";
    cin >> livre.auteur;
    cout << "annee = ";
    cin >> livre.annee;
    cout << "editeur = ";
    cin >> livre.editeur;
    cout << "prix = ";
    cin >> livre.prix;
    ofstream write("livres",ios::app);
    write.write (( char *)&livre, sizeof livre );
    write.close ();}
 void affiche ()
 {
    livres livre;
    ifstream read ("livres");
    read.read (( char *)&livre,sizeof livre);
    while (read)
    {
        cout << "num : " << livre.num
             << "  | isbn : " << livre.isbn
             << "  | titre : " << livre.titre
             << "  | auteur : " << livre.auteur
             << "  | editeur : " << livre.editeur
             << "  | annee : " << livre.annee
             << "  | prix : " << livre.prix
             << endl;
        read.read (( char *)&livre, sizeof livre);
    }
    read.close ();
}

private:
    int isbn;
    char titre[3];
    char auteur[3];
    char editeur[3];
    int annee;
    int prix;
    int num;
};

int main()
{
    livres livre;
    livre.creer();
    livre.affiche();
    return 0;
}

Solution

  • Your character array lacks a null character '\0' at the end of it, which causes the program to read past the end of your intended string. The null character is used to mark the end of a string, so any string of length 3 requires an array of length 4 so there is space for the null string at the end. More info here: http://www.cplusplus.com/doc/tutorial/ntcs/

    You are seeing "abcdefghi" because your three character arrays are stored in contiguous memory. Since there is no '\0' character, the program reads past your first array and finds the next two.

    How are you assigning characters to your arrays? If you initialized them like this:

        char titre[3] = "abc";
    

    You should see a compile error

        error: initializer-string for array of chars is too long [-fpermissive] 
        char titre[3] = "abc";
    

    The compiler knows "abc" is too long because it needs that 4th space for a null character.