1

背景の詳細​​については、こちらを参照してください

を使用しstringstreamてバイナリデータを読み取っています。今のところ、クラスに慣れるためにダミーのプログラムを書いているだけです。これが私のプログラムです:

#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>

using namespace std;

string bytes2hex(char* bytes, int n){
    stringstream out;
    for (int i = 0;i < n;i++){
        out << setfill ('0') << setw(2) << hex << (int) bytes[i] << " ";
    }

    string st = out.str();
    for(short k = 0; k < st.length(); k++)
    {
        st[k] = toupper(st[k]);
    }

    return st;
}

int main(){
    stringstream ss;

    ss << "hello the\0re my\0\0\0 friend";

    while (ss.peek() != EOF){
        char buf [2];
        ss.get(buf, 3);
        cout << buf << "\t==>\t" << bytes2hex(buf, 2) << endl;
    }
}

出力:

he  ==> 68 65 
ll  ==> 6C 6C 
o   ==> 6F 20 
th  ==> 74 68 
e   ==> 65 00 
    ==> 00 00 

これについて 2 つの質問があります。

  1. を実行するときss.get()、一度に 2 文字ずつストリームを読み取るために、2 ではなく 3 を入力しなければならないのはなぜですか?
  2. 最初のヌル文字で終了するのはなぜですか? また、それを防ぐにはどうすればよいですか?
4

2 に答える 2

4

最初の質問について:
istream::get読み取り内容の有効な C スタイルの文字列を形成したいので、渡すバッファーサイズよりも 1 文字少ない文字を読み取り'\0'、最後の位置に文字を格納するように指定されています。実際には、 3 バイトの長さに
拡張する必要もあるため、境界内に留まります。bufss.get

2 番目の質問について:
最初の文字でのカットオフは、'\0'文字列ストリームへの挿入時に既に発生しています。その理由は、C スタイルの文字列 (および文字列リテラルを含む) を挿入すると、コードは最初の'\0'文字で処理を停止するためです。これは C スタイルの文字列の定義であるためです。

次の方法で、stringstream にデータを正しく入力できます。

ss << string("hello the\0re my\0\0\0 friend", 25);

25、バイナリ入力の長さに由来します。

于 2013-01-03T17:06:06.433 に答える
2

istream.getは、テキストデータの読み取りに使用され、n-1文字が読み取られるか検出されると読み取りが停止します\n。バイナリデータを読み取りたい場合は、次を使用します。

ss.read(buf, 2)

于 2013-01-03T16:56:00.427 に答える