istream_iterator 0x9-0xD 上的行为
istream_iterator behaviour on 0x9-0xD
我写了一个小测试文件来弄清楚问题:
#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;
}
现在,预期输出将是
0 - 0
0x1 - 0x1
0x2 - 0x2
...
0x1e - 0x1e
0x1f - 0x1f
但是,我得到 0x9-0xD 的以下输出:
0x8 - 0x8
0x9 - 0x7f
0xa - 0x7f
0xb - 0x7f
0xc - 0x7f
0xd - 0x7f
0xe - 0xe
谁能解释为什么我会得到这个结果?
当你构造字符串 s
时你有 undefined behavior。您没有提供 "string" 的长度 &c
导致构造函数在搜索字符串终止符时 越界 。
您需要在此处明确提供长度:
std::string s(&c, 1);
如果您解决了已经提到的问题(使用 std::string 构造函数),您将得到
0x8 - 0x8
0x9 - 0
0xa - 0
0xb - 0
0xc - 0
0xd - 0
0xe - 0xe
这仍然是未定义的行为,因为您在 output
为空时解除引用。它为空的原因是流忽略空格 - 它们被视为分隔符。
将您的 printf 更改为
printf("%#x - %#x\n", c, !output.empty() ? output.c_str()[0] : -1);
给予
0x8 - 0x8
0x9 - 0xffffffff
0xa - 0xffffffff
0xb - 0xffffffff
0xc - 0xffffffff
0xd - 0xffffffff
0xe - 0xe
我写了一个小测试文件来弄清楚问题:
#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;
}
现在,预期输出将是
0 - 0
0x1 - 0x1
0x2 - 0x2
...
0x1e - 0x1e
0x1f - 0x1f
但是,我得到 0x9-0xD 的以下输出:
0x8 - 0x8
0x9 - 0x7f
0xa - 0x7f
0xb - 0x7f
0xc - 0x7f
0xd - 0x7f
0xe - 0xe
谁能解释为什么我会得到这个结果?
当你构造字符串 s
时你有 undefined behavior。您没有提供 "string" 的长度 &c
导致构造函数在搜索字符串终止符时 越界 。
您需要在此处明确提供长度:
std::string s(&c, 1);
如果您解决了已经提到的问题(使用 std::string 构造函数),您将得到
0x8 - 0x8
0x9 - 0
0xa - 0
0xb - 0
0xc - 0
0xd - 0
0xe - 0xe
这仍然是未定义的行为,因为您在 output
为空时解除引用。它为空的原因是流忽略空格 - 它们被视为分隔符。
将您的 printf 更改为
printf("%#x - %#x\n", c, !output.empty() ? output.c_str()[0] : -1);
给予
0x8 - 0x8
0x9 - 0xffffffff
0xa - 0xffffffff
0xb - 0xffffffff
0xc - 0xffffffff
0xd - 0xffffffff
0xe - 0xe