std :: fstream читает блок данных из файла и записывает данные обратно в файл до EOF

Исключение нулевого указателя - это индикатор того, что вы используете объект, не инициализируя его.

Например, ниже - класс ученика, который будет использовать его в нашем коде.

public class Student {

    private int id;

    public int getId() {
        return this.id;
    }

    public setId(int newId) {
        this.id = newId;
    }
}

Приведенный ниже код дает вам исключение с нулевым указателем.

public class School {

    Student obj_Student;

    public School() {
        try {
            obj_Student.getId();
        }
        catch(Exception e) {
            System.out.println("Null Pointer ");
        }
    }
}

Поскольку вы используете Obj_Student, но вы забыли инициализировать его, как в правильном коде, показанном ниже:

public class School {

    Student obj_Student;

    public School() {
        try {
            obj_Student = new Student();
            obj_Student.setId(12);
            obj_Student.getId();
        }
        catch(Exception e) {
            System.out.println("Null Pointer ");
        }
    }
}
0
задан zebanovich 9 April 2019 в 18:58
поделиться

1 ответ

Ваш код плохо обрабатывает условие EOF и оставляет поток в плохом состоянии после попытки чтения после конца файла. В моей системе это приводит к тому, что все дальнейшие вызовы потока не имеют никакого эффекта. Могу поспорить, что это не так в вашей системе (что, как я подозреваю, является ошибкой в ​​реализации iostream). Я заново сделал ваш код для правильной обработки условия EOF, а также для того, чтобы быть намного чище несколькими другими способами:

#include <fstream>
#include <iostream>

using namespace std;

const int BLOCK_SIZE = 3;

int main()
{
    // open file
    fstream file;
    file.open("sample.txt", ios::binary | ios::out | ios::in);


    // we will read data here
    bool found_eof = false;

    // read blocks of data and write data back
    while (!found_eof)
    {
        unsigned char data[BLOCK_SIZE] = {0};
        char * const data_as_char = reinterpret_cast<char *>(data);
        streampos const pos = file.tellp();
        int count_to_write = BLOCK_SIZE;
        cout << "before read:\t" << file.tellg() << ' ' << pos << '\n';

        // read block
        if (!file.read(data_as_char, BLOCK_SIZE)) {
           found_eof = true;
           count_to_write = file.gcount();
           file.clear();
           cout << "Only " << count_to_write << " characters extracted.\n";
        }
        cout << "after read:\t" << file.tellg() << ' ' << file.tellp() << '\n';

        // write same block back to same position
        file.seekp(pos);
        cout << "before write:\t" << file.tellg() << ' ' << file.tellp() << '\n';
        file.write(data_as_char, count_to_write);
        cout << "after write:\t" << file.tellg() << ' ' << file.tellp() << '\n';
        file.seekp(file.tellp());
    }

    file.close();

    cin.get();
    return 0;
}

Но это не принципиально отличается. Обе версии работают для меня точно так же. Я на Linux с g ++.

Из связанного с возможным дублированием я бы также предложил добавить это непосредственно перед закрытием } вашего цикла for:

file.seekp(file.tellp());

Я поместил это в свой код в соответствующем место.

0
ответ дан Omnifarious 9 April 2019 в 18:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: