1

圧縮を行うためのコードに取り組んでいて、ビットストリーム クラスを作成しました。

私のビットストリーム クラスは、読み取り中の現在のビットと現在のバイト (unsigned char) を追跡しました。

istream クラスで >> 演算子と get() メソッドを使用した場合、ファイルから次の符号なし文字を読み取る方法が異なることに気付きました。

なぜ異なる結果が得られたのか不思議でした。

元:

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として読み取られます

それらがどのように関連しているのかさえわかりませんか?(それらは互いに 2 の補数ではありませんか?)

ただし、 >> 演算子は unsigned char でも機能するように定義されています ( c++ istream クラス リファレンスを参照してください)。

4

3 に答える 3

2

operator>>フォーマットされた入力用です。"23"にストリーミングすると整数として読み取られ、intトークン間の空白を消費します。get()一方、フォーマットされていないバイト単位の入力用です。

于 2011-07-22T15:42:04.510 に答える
1

テキストを解析しない場合は、operator>>またはを使用しないでくださいoperator<<。追跡が困難な奇妙なバグが発生します。また、何を探すべきかがわからない限り、単体テストに対しても回復力があります。たとえば uint8 の読み取りは、たとえば 9 では失敗します。

編集:

#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

それはアプリオリに明らかではなかったと思います。

于 2011-07-22T15:47:50.313 に答える
0

C ++のフォーマットされた入力( )は、整数ではなく文字としてoperator >>扱います。これは少し面倒ですが、理解できます。charunsigned char

get代わりに、次のバイトを返すを使用する必要があります。

ただし、バイナリフラグのあるファイルを開く場合は、フォーマットされたI/Oを使用しないでください。readwriteおよび関連する関数を使用する必要があります。フォーマットされたI/Oは、バイナリ形式ではなくテキスト形式で動作することを目的としているため、正しく動作しません。

于 2011-07-22T15:44:33.230 に答える