Чтение файла на байты - PullRequest
2 голосов
/ 18 марта 2011

У меня есть простая программа:

#include <cstring>
#include <fstream>

using namespace std;

int main(int argc, char **argv)
{
    cout << "Creating test.txt file..." << endl;

    // Writing to file
    fstream fWrite;
    fWrite.open("./_test_data/test.txt", fstream::out | fstream::trunc);
    if (fWrite.fail()) {
        cout << "Creating test.txt file failed!" << endl;
        fWrite.close();
    } else {
        fWrite << (char) 0x09 << (char) 0x0A << (char) 0x0B;
        fWrite << (char) 0x0C << (char) 0x0D << (char) 0x0E;
        fWrite << flush;

        fWrite.close();
        cout << "test.txt file successfully created." << endl;
    }

    // Reading created file
    cout << "Reading test.txt file..." << endl;
    fstream fRead;
    fRead.open("./_test_data/test.txt", fstream::in);
    if (fRead.fail()) {
        fRead.close();
    } else {
        char character;

        while (true) {
            fRead >> character;

            if (fRead.eof()) {
                cout << (int)character << endl;
                cout << "EOF detected!" << endl;
                break;
            }

            cout << (int)character << endl;
        }
        fRead.close();
    }

    return 0;
}

Она должна просто записывать байты в порядке 09 0A 0B 0C 0D 0E, что делается нормально (проверяется hexdump), но при чтении того же файла он читает первый байткак 0E (= 14 в десятичном виде), а затем приходит EOF ...

Creating test.txt file...
test.txt file successfully created.
Reading test.txt file...
14
14
EOF detected!

Почему?

Ответы [ 4 ]

4 голосов
/ 18 марта 2011

Используйте fRead.read(&character,1) вместо fRead >> character.

Но вы также можете удалить cout << (int)character << endl; в операторе if.

1 голос
/ 18 марта 2011

Откройте файл в двоичном режиме: fRead.open("...", fstream::in | fstream::binary); - чтобы не допустить преобразования файлового слоя в последовательности новой строки.

0 голосов
/ 19 марта 2011

Попробуйте fRead >> std::noskipws.Оператор >> для потоков чтения пропускает пробелы, чтобы перейти к следующим «интересным» данным.Рассмотрим входной поток, такой как hi there.Считая, что std::string за раз, вы получите hi и there, игнорируя пробел.Одновременно, читая, что символ за раз, вы получаете -hithere- с пропущенным символом пробела.

Байты, которые вы не могли прочитать из fRead, считались пробелом, поэтому они все игнорировались.

Причина, по которой fRead.read() является решением (и хорошим), заключается в том, что он выполняет неформатированный ввод - ему нет дела до пробелов.

Наконец, вы должны сделать эти другиеизменения в вашей программе:

#include <iostream>  // you need this for std::cout and std::endl

Вам нужно iostream для std::cout и std::endl.

fRead.open ("./_ test_data / test.txt", fstream:: in | fstream :: binary);

Вам нужно открыть тестовый файл в двоичном формате (как для записи, так и для чтения), если в нем будут какие-либо непечатные символы.

0 голосов
/ 18 марта 2011

Попробуйте fstream::in | fstream::binary.

...