Считывание с файла. С++

194
11 апреля 2017, 11:42

Почему появляется эта ошибка? Когда я не использую !file2.eof, ошибка не возникает.

Ошибка: Необработанное исключение по адресу 0x7673B727 в Проект1.exe: исключение Microsoft C++: std::bad_alloc по адресу памяти 0x002AF43C.

Вот код:

class foo
{
    string Name;
    int Age;
    public:
    foo() : Name(" "), Age(0){}
    foo(string name, int age) : Name(name), Age(age){}
    void set_p()
    {
        cout << "Enter Name: ";
        cin >> Name;
        cout << "Enter Age: ";
        cin >> Age;
    }
    void show()
    {
        cout << "Name: " << Name << endl;
        cout << "Age: " << Age << endl;
    }
    void write(ostream& os)
    {
        os.write((char*)&Age, sizeof(Age)); // Запись POD-члена
        size_t len = Name.length() + 1;       // Длина с нулевым байтом
        os.write((char*)&len, sizeof(len)); // Запись длины
        os.write((char*)Name.c_str(), len);  // Запись данных
    }
    void read(istream& in)
    {
        in.read((char*)&Age, sizeof(Age));   // Чтение POD-члена
        size_t len;                         // Переменная для длины
        in.read((char*)&len, sizeof(len));  // Чтение длины записанной строки
        char * buf = new char[len];         // Выделение буфера для чтения
        in.read(buf, len);                   // Чтение (с нулевым байтом)
        Name = buf;                         // Присвоение считанной строки члену
        delete[]buf;                        // Освобождение памяти
    }
};
int main()
{
    foo obj("Oleh", 20);
    foo obj2;
    ofstream file;
    file.open("file.bin", ios::binary );
    obj.write(file);
    obj.set_p();
    obj.write(file);
    file.close();
    ifstream file2;
    file2.open("file.bin", ios::binary);
    file2.seekg(0);
    while (!file2.eof())
    {
        obj2.read(file2);
        obj2.show();
    }
    file2.close();
    _getch();
    return 0;
}
Answer 1

По-моему, эта ошибка - самая распространенная в SO...

while (!file2.eof())

Так делать НЕЛЬЗЯ.
Потому что признак конца файла выставляется ПОСЛЕ неудачного чтения!
Только после того, как была неудачная попытка что-то прочесть за концом файла - только тогда eof() вернет true.

Update
Вот вариант:

bool read(istream& in)
{
    int tAge;
    in.read((char*)&tAge, sizeof(tAge));   // Чтение POD-члена
    size_t len;                         // Переменная для длины
    in.read((char*)&len, sizeof(len));  // Чтение длины записанной строки
    char * buf = new char[len];         // Выделение буфера для чтения
    in.read(buf, len);                   // Чтение (с нулевым байтом)
    if (in)                             // read OK
    {
        Name = buf;                         // Присвоение считанной строки члену
        Age = tAge;
    }
    delete[]buf;                        // Освобождение памяти
    return !!in;
}

Функция возвращает true только когда все успешно считано. При сбоях она не только возвращает false, но и ничего не пишет в объект - он остается в том же состоянии, что и до чтения (обеспечение транзакции - или все, или ничего; для этого и читаем сначала в tAge).

Ну, а цикл имеет вид:

while (obj2.read(file2))
{
    obj2.show();
}
READ ALSO
Проблема с boost

Проблема с boost

Компилирую проект с бустомКомпилируется нормально, при линковке постоянно вылетает ошибка:

331
Как исправить reduce/reduce конфликт?

Как исправить reduce/reduce конфликт?

Я пытаюсь написать парсер функций и переменных С++

222
QSqlQuery возвращает некоректные данные

QSqlQuery возвращает некоректные данные

ЗдравствуйтеТретий день бьюсь над проблемой

220