在C++中使用字符的标准字符串行为

问题描述:

我有一个我不明白的问题。我将字符添加到标准字符串。我把它们拿出来打印的价值不是我所期望的。在C++中使用字符的标准字符串行为

int main (int argc, char *argv[]) 
{ 
    string x; 
    unsigned char y = 0x89, z = 0x76; 
    x += y; 
    x += z; 
    cout << hex << (int) x[0] << " " <<(int) x[1]<< endl; 
} 

输出: ffffff89 76

我期待什么: 89 76

任何想法,这里发生了什么? 我该如何解决?

+1

那么你会期待什么? – Howard

+0

哪里定义了“z”?好的,我现在在编辑中看到它。 – danishgoel

+0

永远不要使用隐式转换! – KillianDS

您必须考虑到char可能会被签名的事实。如果您直接将其升级至int,则签名值将被保留。相反,首先必须将其转换为相同宽度的无符号类型(即unsigned char)以获得所需的值,然后然后将该值提升为整数类型以获得正确的格式化打印。

全部放在一起,你想是这样的:

std::cout << (int)(unsigned char)(x[0]); 

或者,使用C++ - 风格的转换:

std::cout << static_cast<int>(static_cast<unsigned char>(x[0])) 

字符串运算符[]产生char,即有符号值。当你将其转换为int进行输出时,它也是一个有符号值。

投到char的输入值是负值,因此int也是。因此你可以看到你描述的输出。

+2

请记住,'char'是'signed'还是'unsigned'是实现定义的。 –

+0

+1:但是如果默认的字符类型被签名或者不是依赖于实现的 – 6502

+0

这也是我的想法。我只是测试它,这是'0x79'出现正确的情况,但随后它的'ffffffxx'。 – danishgoel

最有可能的是charsigned的平台上,因此0x890x76当它是由char代表成为负数。

您对确保该字符串有unsigned charvalue_type,所以这应该工作:

typedef basic_string<unsigned char> ustring; //string of unsigned char! 

ustring ux; 
ux += y; 
ux += z; 
cout << hex << (int) ux[0] << " " <<(int) ux[1]<< endl; 

它打印出你认为应该打印:

89 76 

在线演示:http://www.ideone.com/HLvcv

+0

“0x76”不应该(也不会)变为负数。 –

+0

另外(尽管与你的观点无关),'basic_string '是未定义的行为。很多实现(VC++和g ++,至少)都是这样定义的,但不一定采用相同的方式。 –

+0

@JamesKanze:为什么'basic_string '是未定义的行为? – Nawaz

数量0x89137 10进制。它超过了the cap of 127,现在是负数,因此您在那里看到那些ffffff。你可以简单地insert (unsigned char) after the (int) cast。你会得到所需的结果。

-Sandip