C ++ iostream >> оператор ведет себя иначе, чем get () без знака char - PullRequest
1 голос
/ 22 июля 2011

Я работал над фрагментом кода для некоторого сжатия и написал класс потока битов.

Мой класс потока битов отслеживал текущий бит, который мы читаем, и текущий байт (беззнаковый символ).

Я заметил, что чтение следующего неподписанного символа из файла происходило иначе, если я использовал метод >> operator vs get () в классе istream.

Мне было просто любопытно, почему я былполучить разные результаты?

ex:

this->m_inputFileStream.open(inputFile, std::ifstream::binary);   
unsigned char currentByte;
this->m_inputFileStream >> currentByte;

против

this->m_inputFileStream.open(inputFile, std::ifstream::binary);
unsigned char currentByte;
this->m_inputFileStream.get((char&)currentByte);

Дополнительная информация:

Если быть точным, то байт, который я читал, был0x0A, однако, при использовании >> он будет читаться как 0x6F

Я не уверен, как они вообще связаны?(они не являются дополнением 2s друг к другу?)

Оператор >> также определен для работы и с неподписанным символом (см. справочник по классу istream c ++

Ответы [ 3 ]

2 голосов
/ 22 июля 2011

operator>> для отформатированного ввода . Он будет читать "23" как целое число, если вы передадите его в int, и он будет использовать пробелы между токенами. get() с другой стороны - для неотформатированный , побайтный ввод.

1 голос
/ 22 июля 2011

Если вы не анализируете текст, не используйте operator>> или operator<<.Вы получите странные ошибки, которые трудно отследить.Они также устойчивы к юнит-тестам, если вы не знаете, что искать.Например, чтение uint8 не удастся на 9.

edit:

#include <iostream>
#include <sstream>
#include <cstdint>

void test(char r) {
        std::cout << "testing " << r << std::endl;
        char t = '!';
        std::ostringstream os(std::ios::binary);
        os << r;
        if (!os.good()) std::cout << "os not good" << std::endl;
        std::istringstream is(os.str(), std::ios::binary);
        is >> t;
        if (!is.good()) std::cout << "is not good" << std::endl;
        std::cout << std::hex << (uint16_t)r 
             << " vs " << std::hex << (uint16_t)t << std::endl;
}

int main(int argc, char ** argv) {
        test('z');
        test('\n');
        return 0;
}

производит:

testing z
7a vs 7a
testing 

is not good
a vs 21

Я полагаю, что априори никогда не было бы очевидным.

0 голосов
/ 22 июля 2011

Форматированный ввод C ++ (operator >>) обрабатывает char и unsigned char как символ, а не как целое число.Это немного раздражает, но понятно.

Вы должны использовать get, который вместо этого возвращает следующий байт.

Однако, если вы открываете файл с двоичным флагом, выне следует использовать форматированный ввод / вывод.Вы должны использовать read, write и связанные с ними функции.Отформатированный ввод / вывод не будет работать правильно, так как он предназначен для работы с текстовыми форматами, а не с двоичными.

...