Updating end of file in C ++ fstream

I wrote this code:

#include <fstream> #include <iostream> using namespace std; struct Man { int ID; char Name[20]; }; void Add(); void Update(); void Print(); int main() { int n; cout << "1-add, 2-update, 3-print, 5-exit" << endl; cin >> n; while (n != 5) { switch (n) { case 1: Add(); break; case 2: Update(); break; case 3: Print(); break; } cout << "1-add, 2-update, 3-print, 5-exit" << endl; cin >> n; } return 0; } void Add() { fstream file; file.open("Data.dat", ios::in | ios::out | ios::binary); if (file.is_open()) { int id; Man man; bool didFound = false; cout << "ID : "; cin >> id; file.read((char*)&man, sizeof(Man)); while (!file.eof() && !didFound) { if (man.ID == id) { cout << "Already exist" << endl; didFound = true; } file.read((char*)&man, sizeof(Man)); } if (!didFound) { man.ID = id; cout << "Name: "; cin >> man.Name; file.clear(); file.seekp(0, ios::end); file.write((char*)&man, sizeof(Man)); } } } void Update() { fstream file; file.open("Data.dat", ios::in | ios::out | ios::binary); if (file.is_open()) { int id; Man man; bool didFound = false; cout << "ID : "; cin >> id; file.read((char*)&man, sizeof(Man)); while (!file.eof() && !didFound) { if (man.ID == id) { cout << "Name: "; cin >> man.Name; file.seekp((int)file.tellg() - sizeof(Man), ios::beg); file.write((char*)&man, sizeof(Man)); didFound = true; } file.read((char*)&man, sizeof(Man)); } file.close(); if (!didFound) { cout << "Cant update none existing man" << endl; } } } void Print() { fstream file; file.open("Data.dat", ios::in | ios::binary); if (file.is_open()) { int id; Man man; bool didFound = false; cout << "ID\tName" << endl; file.read((char*)&man, sizeof(Man)); while (!file.eof()) { cout << man.ID << '\t' << man.Name << endl; file.read((char*)&man, sizeof(Man)); } file.close(); } } 

But I have a problem with the Update function: When I update the last Person in the file, when it reaches the file.read file, the file writes the value of the last Person (in the file before writing) to the end of the file (after the updated person).

I added this after file.write and it seems to have solved:

 file.seekg(file.tellp(), ios::beg); 

Can someone explain why?

(yes, this can be solved with else)

+4
source share
1 answer

Somewhat arbitrary, you must run seek between read and write . It is not specified in the standard, but in the C ++ standard it is mentioned that C ++ fstream has the same properties as C stdio streams with respect to the validity of stream operations, and in the C standard it is mentioned that a positioning and writing command is required between reads ( or vice versa).

Some platforms weaken requirements. GCC after version 4.5 or 4.6, I personally changed basic_filebuf to eliminate the Byzantine rule.

By the way, file.seekg( 0, ios::cur ) safer.

+4
source

Source: https://habr.com/ru/post/1482029/


All Articles