70

私は通常、stringstreamメモリ内の文字列に書き込むために使用します。バイナリモードでcharバッファに書き込む方法はありますか? 次のコードを検討してください。

stringstream s;
s << 1 << 2 << 3;
const char* ch = s.str().c_str();

のメモリは次のchようになります: 0x313233 - 文字 1、2、および 3 の ASCII コード。バイナリ値自体を書き込む方法を探しています。つまり、メモリに 0x010203 が必要です。問題は、関数を記述できるようにしたいということです

void f(ostream& os)
{
    os << 1 << 2 << 3;
}

そして、使用するストリームの種類を外部で決定します。このようなもの:

mycharstream c;
c << 1 << 2 << 3; // c.data == 0x313233;
mybinstream b;
b << 1 << 2 << 3; // b.data == 0x010203;

何か案は?

4

7 に答える 7

44

文字列ストリームを含むストリームにバイナリ データを読み書きするには、read() および write() メンバー関数を使用します。そう

unsigned char a(1), b(2), c(3), d(4);
std::stringstream s;
s.write(reinterpret_cast<const char*>(&a), sizeof(unsigned char));
s.write(reinterpret_cast<const char*>(&b), sizeof(unsigned char));
s.write(reinterpret_cast<const char*>(&c), sizeof(unsigned char));
s.write(reinterpret_cast<const char*>(&d), sizeof(unsigned char));

s.read(reinterpret_cast<char*>(&v), sizeof(unsigned int)); 
std::cout << std::hex << v << "\n";

これは0x4030201私のシステムに与えます。

編集: 挿入演算子と抽出演算子 (<< および >>) を使用してこれを透過的に機能させるには、正しいことを行う派生 streambuf を作成し、それを使用するストリームに渡すのが最善の策です。

于 2009-10-13T11:14:30.430 に答える
4

まあ、整数ではなく文字を使用してください。

s << char(1) << char(2) << char(3);
于 2009-10-13T10:05:45.313 に答える
3

いくつかの異常な演算子をオーバーロードすると、かなりうまく機能します。以下では、 <=をオーバーロードすることを選択しました。これは、左から右への結合性が<<と同じであり、ルック アンド フィールがどういうわけか似ているためです ...

#include <iostream>
#include <stdint.h>
#include <arpa/inet.h>

using namespace std;

ostream & operator<= (ostream& cout, string const& s) {
    return cout.write (s.c_str(), s.size());
}
ostream & operator<= (ostream& cout, const char *s) {
    return cout << s;
}
ostream & operator<= (ostream&, int16_t const& i) {
    return cout.write ((const char *)&i, 2);
}
ostream & operator<= (ostream&, int32_t const& i) {
    return cout.write ((const char *)&i, 4);
}
ostream & operator<= (ostream&, uint16_t const& i) {
    return cout.write ((const char *)&i, 2);
}
ostream & operator<= (ostream&, uint32_t const& i) {
    return cout.write ((const char *)&i, 4);
}

int main() {
    string s("some binary data follow : ");

    cout <= s <= " (machine ordered) : " <= (uint32_t)0x31323334 <= "\n"
         <= s <= " (network ordered) : " <= htonl(0x31323334) ;
    cout << endl;

    return 0;
}

いくつかの欠点があります。

  • <=の新しい意味は、読者を混乱させたり、予期しない結果につながる可能性があります。

    cout <= 31 <= 32;
    

    と同じ結果は得られません

    cout <= (31 <= 32);
    
  • 上記の例に示されているように、エンディアンはコードを読むときに明確に言及されていません。

  • 同じ優先順位のグループに属していないため、単純に<<と混在させることはできません。私は通常、括弧を使用して次のように明確にします。

    ( cout <= htonl(a) <= htonl(b) ) << endl;
    
于 2013-03-15T17:39:51.433 に答える