-2

我写了一个小测试文件来说明问题:

#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

谁能解释我为什么得到这个结果?

4

2 回答 2

2

构造字符串时有未定义的行为s。您没有提供您提供的“字符串”的长度,&c导致构造函数越界搜索字符串终止符。

您需要在此处明确提供长度:

std::string s(&c, 1);
于 2017-07-25T13:37:28.400 回答
2

如果您解决了已经提到的问题(使用 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
于 2017-07-25T13:56:15.737 回答