This is a very beta peice of code in a function I am working on that will write records to a file (casted as character data). I'm using an overloaded operator to set values in a class called Account. My teacher insists that I use the account as a way to point to where each record is held, so I get the account number from a get function (its a private data member, yes i could make it public). When I open the file, I set it to append the data. In theory, and i'm probably wrong, but if I point to the same position on the file, the program should overwrite that data. For instance, i type in account 10, add data, then add data again and type 10 for the account, I should only get one entry. Instead, I get 2 entries both with account 10. I want to append data but I want to rewrite what is there.

do
	{
		cin >> a;
		accntNum = a.getNumber();
		outAccount.seekp( (accntNum - 1) * classSize);
		outAccount.write( reinterpret_cast<const char*>(&a), (classSize) );
		cout << "Another? [Y - N]: ";
		cin >> again;
		again = toupper(again);
	}while(again == 'Y');
	outAccount.close();
}

All the threads I've come across reference this way of using seekp to point to a position and then writing to it, but I have no idea why it refuses to overwrite an exact position. If you would like to see more code, I'd be happy to post it. classSize is passed to the function from main and is declared as int classSize = sizeof(Account); Thank you!

Here ya go. My teacher's C++ book informed me that it is a shortcut to open accounts.dat this way instead of calling outAccount.open() directly. I appologize if this isn't the right way to do it.

void addData(Account a, int classSize)
{
	int accntNum;
	char again;
	
	ofstream outAccount( "accounts.dat", ios::app);
	
	do
	{
		cin >> a;
		accntNum = a.getNumber();
		outAccount.seekp( (accntNum - 1) * classSize);
		outAccount.write( reinterpret_cast<const char*>(&a), (classSize) );
		cout << "Another? [Y - N]: ";
		cin >> again;
		again = toupper(again);
	}while(again == 'Y');
	outAccount.close();
}

Your teacher is correct. The reason your program does not work the way you want it to is because of the ios::app flag you added when opening the file. If you read the description here you will see that the ios::app

Set the stream's position indicator to the end of the stream before each output operation

All you really need is the ios::binary flag since you are writing the Account class as binary data ofstream outAccount( "accounts.dat", ios::binary);

This article has been dead for over six months. Start a new discussion instead.