c++ - std::cout 未正确打印由 unsigned char 数组的 reinterpret_cast 创建的 std::string

标签 c++ cout stdstring reinterpret-cast

我有一个存储 1 字节十六进制字符的 unsigned char 数组,我想对这些值进行按位运算。

在使用 reinterpret_cast 将它们转换为字符串后(使用 std::stringstream 和 std::bitset 来执行必要的操作),我尝试打印字符串以查看内容是什么。奇怪的是,我注意到 std::cout 没有给出预期的结果,但是使用 printf 却给出了预期的结果!

这是一个简单的例子:

int main(int argc, char *argv[])
{

    unsigned char my_txt[] = {
        0x52, 0x5f, 0x73, 0x68, 0x7e, 0x29, 0x33, 0x74, 0x74, 0x73, 0x72, 0x55
    };
    unsigned int my_txt_len = 12;

    std::string my_std_string(reinterpret_cast<const char *>(my_txt), my_txt_len);

    for (size_t i=0;i<my_txt_len;i++)
        printf("%02X ", my_std_string[i]);      // Works fine!
    printf("\n");

    std::cout << my_std_string << std::endl;    // Bad stuff happens :S

    return 0;
}

输出:

52 5F 73 68 7E 29 33 74 74 73 72 55     // Expected
R_sh~)3ttsrU                            // ??

决心找到一个解决方案,我修修补补了一会儿 - 猜测 reinterpret_cast 可能会导致这种行为。我最终发现这样做:

std::cout << std::hex << (int)my_std_string[0] << std::dec << std::endl;

产生了预期的结果,至少第一个字符是这样。通过循环迭代也为其他 11 个字节提供了正确的值。

有人能解释为什么这会发生在 std::cout 上而不是 printf 上吗?起初,我认为也许我需要将其转换回 unsigned char 但这样做没有任何效果。为什么转换为 int 会给出正确的输出?

在我使用过 reinterpret_cast 之后,对存储在字符串中的值进行按位运算是否安全?我突然想到所有这些可能毫无意义,因为我相信我可以直接对 unsigned char 进行二进制数学运算,不是吗?此处的建议将不胜感激。

对于那些好奇的人,我正在尝试编写自定义 C++ 控制台应用程序(Windows 7 64 位计算机上的 Microsoft Visual Studio 2010)以使用供应商的 API 与 CAN-USB 适配器连接。我希望接收(作为更大的“接收帧”结构的一部分)具有十六进制值的 8 字节无符号字符数组,我需要处理这些值以获得我的应用程序可用的数据。然后将处理后的数据存储在 Protocol Buffer 中,以便在 matlab 中进一步解释。

抱歉,如果这看起来像一个愚蠢的问题 - 我来自硬件背景并且有一段时间没有做过任何认真的编程(关于 SO 的第一篇文章!)。

最佳答案

改变

std::cout << my_std_string << std::endl;    // Bad stuff happens :S

for( std::size_t i = 0; i < my_txt_len ; i++ )
{
    std::cout << std::hex << static_cast<unsigned>(my_std_string[i]) << " " ;
}
std::cout << std::endl;

A std::string是字符串的表示,而不是纯粹的字节数组。因此,将其传递给 std::cout将显示一个字符串。你的printf正在打印您的 unsigned char 的单个值大批。与此等效的 STL 是 std::vector<unsigned char> .

您需要添加 static_cast<unsigned>() .否则std::cout将打印每个 unsigned char值作为 char ascii 字符。输出将为 R _ s h ~ ) 3 t t s r U .您必须通过隐式告诉它来阻止这种转换。

关于c++ - std::cout 未正确打印由 unsigned char 数组的 reinterpret_cast 创建的 std::string,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24619154/

相关文章:

c++ - C++ VS 2010 OpenCV 中 FindFirstFile 参数的 Concat 命令行参数

C++ Unicode 问题

c++ - 在 C++11 中,将引用/指针返回到 std::string 中某个位置的最高效方法是什么?

c++ - 如何从 std::vector<string> 构造 std::string?

c++ - 在 Makefile 中处理多个扩展的优雅方法

c++ - 模板参数列表中参数 3 的类型/值不匹配

c++ - 线程安全的 cout 技术。我错过了什么吗?

c++ - C++ cout和cin执行错误: main.cpp: In function ‘int main()’

c++ - 仅对 QTableView 中的列显示 gridLine

c++ cout如何打印char*