1

The read method returns the last object twice. I tried using tellg before read line and it seems as if the last object itself is written twice in file.

#include<iostream>
#include<fstream>
#include<string>
using namespace std;
class Abc
{
    string uname, pword;
public:
    void getdetails()
    {
        cout << "enter a password";
        getline(cin, pword);
        cout << "enter username";
        getline(cin, uname);
    }
    void printdetails()
    {
        cout << uname << " " << pword;
    }
};
int main()
{
    fstream f;
    int i, j;
    f.open("gamma.txt", ios::out | ios::binary | ios::app);
    Abc a;
    for (i = 0; i < 2; i++)
    {
        a.getdetails();
        f.write((char*) &a, sizeof(a));
    }
    f.close();
    f.open("gamma.txt", ios::in | ios::binary);
    for (i = 0; i < 2; i++)
    {
        f.read((char*) &a, sizeof(a));
        a.printdetails();
    }
    f.close();
}

This is the output. Instead of getting both the objects I'm getting the second one twice.

enter a password
123
enter username
ralph
enter a password
321
enter username
john
john 321john 321
James Z
  • 12,209
  • 10
  • 24
  • 44
  • 1
    You did not check the read worked. So the last read is failing and you are simply printing the random content of `a` which just happens to be what was in the object before the last read. To verify this clear the content before reading see what happens. To fix only print if the read succeedes. – Martin York Aug 18 '20 at 23:25
  • PS. Reading and writing strings like that is problematic (very wrong) as the objects uname and pword are objects with constructors and stuff. – Martin York Aug 18 '20 at 23:29

1 Answers1

0

You cannot legally read and write anything you like. In particular, in your case, it's not OK to read or write a struct containing a string. Doing so leads to undefined behaviour.

Only so called POD types can be read or written in the way you are trying to do.

john
  • 85,011
  • 4
  • 57
  • 81
  • It seems a little strange to say *You cannot legally read and write anything* and then follow it up with *Only so called POD types can be read or written in the way you are trying to do.*. Unless I'm missing something the answer seems to be contradicting itself. – NathanOliver Aug 18 '20 at 21:53
  • @NathanOliver maybe if you read 'anything' as 'any old thing' rather than 'anything at all'. I've tried to clarify. – john Aug 18 '20 at 21:55
  • @NathanOliver I know my answer is a little vague, but this is a tricky topic to explain to a beginner and the last time I tried I was simply not believed. Short string optimization doesn't help because then sometimes it can seem to work. If you know of a good duplicate I'll be happy to give up my answer to that. – john Aug 18 '20 at 21:57
  • @john I searched for POD types and tried using char arrays instead of string and it worked. Thanks! – am_rendra9 Aug 18 '20 at 22:12
  • @am_rendra9 That's one option. I'm glad my answer helped. It is possible to read and write strings but you can't do it in a single step. E.g. you could write the length of the string first and then the characters of the string second. When reading first read the length, then construct a string of that length, and then finally read the characters into the newly constructed string. – john Aug 18 '20 at 22:17