在c ++ fstream中更新文件的结尾

时间:2013-05-21 19:34:16

标签: c++ fstream

我写了这段代码:

#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();
    }
}

但我在Update函数中遇到问题: 当我更新文件中的最后一个Man时,当它到达file.read时,文件会将最后一个Man的值(在写入之前的文件中)写入文件的末尾(在更新后的man之后)

我在file.write之后添加了它,它似乎解决了它:

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

有人可以解释原因吗?

(是的,可以用其他方法解决)

1 个答案:

答案 0 :(得分:4)

有些随意,您需要在seekread之间执行write。它没有在标准中详细说明,但C ++标准提到C ++ fstream具有与C stdio流相同的属性,与流操作的有效性有关,C标准提到了定位命令在阅读和写作之间需要(反之亦然)。

有些平台放宽了要求。 GCC在4.5或4.6之后,我亲自修改basic_filebuf以消除拜占庭规则。

顺便说一下,file.seekg( 0, ios::cur )更安全。