简体   繁体   中英

read binary data from `stringstream`

for more background, see here

I am using a stringstream to read through binary data. As of now, I am simply writing a dummy program to get comfortable with the class. Here's my program:

#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;
    }
}

Output:

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

I have 2 questions on this:

  1. Why is it that, when I execute ss.get() , I have to input 3, rather than 2, to read the stream 2 characters at a time?
  2. Why does it terminate on the first null character, and how do I prevent that from happening?

Regarding the first question:
istream::get wants to form a valid C-style string of what it reads, so it is specified to read one character less than the buffersize you pass and to store a '\\0' character in the last position.
Actually, you should also extend buf to be 3 bytes long, so ss.get will remain within the bounds.

Regarding the second question:
The cut-off at the first '\\0' character alread happens on the insertion into the stringstream. The reason is that, when you insert a C-style string (and that includes string literals), the code stops processing it at the first '\\0' character, because that is the definition of a C-style string.

You can fill your stringstream correctly with data in this way:

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

where the 25 comes from the length of your binary input.

istream.get is used to read text data and the reading stop when either n-1 characters are read or \\n is encountered. If you want to read binary data then use this:

ss.read(buf, 2)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM