Reputation: 845
I have written a small test file to make the question clear :
#include <iostream>
#include <iterator>
#include <algorithm>
#include <cstdio>
#include <sstream>
void printChar(const char c) {
std::string s(&c);
std::istringstream iss(s);
std::ostringstream oss;
std::copy(std::istream_iterator<char>(iss),
std::istream_iterator<char>(), // reads till the end
std::ostream_iterator<char>(oss));
std::string output = oss.str();
printf("%#x - %#x\n", c, output.c_str()[0]);
}
int main (const int argc, const char** argv) {
for (char i = 0; i < 0x20; ++i) {
printChar(i);
}
return 0;
}
Now, the expected output is going to be
0 - 0
0x1 - 0x1
0x2 - 0x2
...
0x1e - 0x1e
0x1f - 0x1f
However, I get the following output for 0x9-0xD :
0x8 - 0x8
0x9 - 0x7f
0xa - 0x7f
0xb - 0x7f
0xc - 0x7f
0xd - 0x7f
0xe - 0xe
Can anyone explain why I get this result ?
Upvotes: -2
Views: 144
Reputation: 6946
If you fix the issue already mentioned (with the std::string constructor) and you will get
0x8 - 0x8
0x9 - 0
0xa - 0
0xb - 0
0xc - 0
0xd - 0
0xe - 0xe
This is still undefined behaviour because you are dereferencing output
when it is empty. The reason that it is empty is that streams ignore whitespace - they are considered as delimiters.
Changing your printf to
printf("%#x - %#x\n", c, !output.empty() ? output.c_str()[0] : -1);
gives
0x8 - 0x8
0x9 - 0xffffffff
0xa - 0xffffffff
0xb - 0xffffffff
0xc - 0xffffffff
0xd - 0xffffffff
0xe - 0xe
Upvotes: 2
Reputation: 409442
You have undefined behavior when you construct the string s
. You do not provide a length of the "string" you provide with &c
leading the constructor to go out of bounds in search for the string terminator.
You need to provide the length explicitly here:
std::string s(&c, 1);
Upvotes: 2