2011-07-22 8 views
1

圧縮を行うためにコードを作成していましたが、ビットストリームクラスを作成しました。C++ iostream >>演算子は、get()とは異なる動作をします。unsigned char

私のビットストリームクラスは、読み込み中の現在のビットと現在のバイト(符号なしchar)を追跡していました。

istreamクラスで>>演算子vs 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としてそれを読んでいました

どのように関連性があるのか​​わかりません。 (彼らはお互いの補数じゃない?)>>演算子はまた、しかし同様にunsigned char型のために働くように定義されている

c++ istream class reference

+0

"differently"を定義してください –

+0

はいくつかの詳細について質問を更新しました – Setheron

答えて

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 

私はそれが先験的に明らかにされてなかっただろうと仮定します。

+0

になります。最初の文はOKです。残りは物事の一般的な文脈でただbalderdashです。いくつかの**具体的な**例があれば建設的な入力でなければならないことを意味します。そうでなければ、それはゴミとみなされ、否定的な投票の対象となります。 –

+0

私はそれがどのように不正確な値になっているのか見ていますが、なぜ私はまだ不明です。 – Setheron

+0

バイナリでは、0x0Aは '\ n'と同じです。ただし、 '\ n'はテキスト形式のストリームで特別な意味を持ちます。シフト演算子は、(私が理解する限り)バイナリストリームに対する非センス演算です。私は彼らがいつも失敗しない理由を理解していない*。 istream/ostreamインターフェイスで読み書きメソッドを使用すると、このような問題は発生しません。 –

2

operator>>書式付き入力です参照してください。それはよあなたはintにそれをストリーミングする場合は整数として"23"を読んで、そしてそれは、トークンの間に空白を食べるよ。get()一方、バイト単位の入力、未フォーマットためである。

+0

正解。しかし、OPは、フォーマットされた入力に対してintではなくunsigned charを使用しています。それがどう変わるか説明できますか? –

+0

。私は無署名のcharを使用していたので、unsigned charを与えるべきですか? – Setheron

+0

あなたはまだトークンでトークンを読んでいるので、空白を取得したときに問題になるか、空白で囲まれた1文字でないものにヒットする可能性があります。 –

0

C++の書式付き入力(operator >>)はを扱いますとunsigned charは整数ではなく文字として表示されます。これは少し面倒ですが、わかりやすいものです。

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

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

+1

私はcharを整数として扱う方がずっと面倒だと思います。 << and >>間の対称操作が期待されます。だから私が '0x49'を出力すると、その文字が生成されていても、入力は' 0x49'と読むことを期待します。 'std :: cout << '1'; char x; std :: cin >> x; 'xは文字 '1'(0x49) –

関連する問題