Reputation: 9708
I have a function I need to use in a library which works with a stream. The actual input data is unsigned char buffer with embedded nulls and indeed each byte can be any character/integer from 0-255.
I have the source code to the library and can change it. Given a stream of bytes like this:
0x30, 0xb, 0x0, 0x6, 0x6
If I use a std::istringstream stream constructed from the char buffer, as soon as 0x0 is reached in the read_stream function, peek returns EOF???
When I try to copy the contents of the stream to a vector stream processing is stopping on reaching the null character. How can I fix this. I want to copy ALL the binary characters to the vector.
#include <vector>
#include <iostream>
#include <sstream>
static void read_stream(std::istream& strm, std::vector<char>& buf)
{
while(strm) {
int c (strm.peek());
if(c != EOF) { // for the 3rd byte in stream c == 0xffffffff (-1) (if using istrngstream)
strm.get();
buf.push_back(c);
}
}
}
int main() {
char bin[] = {0x30, 0xb, 0x0, 0x6, 0x6, 0x2b, 0xc, 0x89, 0x36, 0x84, 0x13, 0xa, 0x1};
std::istringstream strm(bin);
std::vector<char> buf;
read_stream(strm, buf);
//works fine doing it this way
std::ofstream strout("out.bin",std::ofstream::binary);
strout.write(bin, sizeof(bin));
strout.close();
std::ifstream strmf("out.bin",std::ifstream::binary);
std::vector<char> buf2;
read_stream(strmf, buf2);
return 0;
}
EDIT:
I realise now that an embeeded null has no special significance in a stream. So this issue must be something to do with istringstream.
Upvotes: 0
Views: 277
Reputation: 20073
What you pass a C style string (char
pointer) to the std::istringstream
constructor it actually instantiates a std::string
and passes that instead. This happens due to an implicit conversion. The conversion constructor of std::string
interprets a null byte character in C style strings as an end of string terminator causing all characters after it to be ignored.
To avoid this you can explicitly construct a std::string
specifying the size of the data and pass it to std::istringstream
char bin[] = {0x30, 0xb, 0x0, 0x6, 0x6, 0x2b, 0xc, 0x89, 0x36, 0x84, 0x13, 0xa, 0x1};
std::istringstream strm(std::string(bin, sizeof(bin) / sizeof(bin[0])));
Note: I don't know exactly what you are trying to accomplish but I recommend using std::vector
instead of a raw character buffer if possible.
Upvotes: 0