Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++中字符的标准字符串行为_C++_String_Std - Fatal编程技术网

C++中字符的标准字符串行为

C++中字符的标准字符串行为,c++,string,std,C++,String,Std,我有一个我不明白的问题。我将字符添加到标准字符串中。当我把它们拿出来时,打印出来的值不是我所期望的 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;

我有一个我不明白的问题。我将字符添加到标准字符串中。当我把它们拿出来时,打印出来的值不是我所期望的

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

你知道这里发生了什么吗? 如何修复它?

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

转换为char的输入值为负数,因此int也将为负数。因此,您可以看到您描述的输出。

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

转换为char的输入值为负数,因此int也将为负数。因此,您可以看到您描述的输出。

最有可能的字符是在您的平台上签名的,因此当用字符表示时,0x89和0x76变为负数

您必须确保字符串的值类型为unsigned char,因此这应该可以:

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;
在线演示:

最有可能的字符是在您的平台上签名的,因此0x89和0x76在用字符表示时变为负数

您必须确保字符串的值类型为unsigned char,因此这应该可以:

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;

在线演示:

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

总而言之,你想要这样的东西:

std::cout << (int)(unsigned char)(x[0]);
或者,使用C++样式转换:

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

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

总而言之,你想要这样的东西:

std::cout << (int)(unsigned char)(x[0]);
或者,使用C++样式转换:

std::cout << static_cast<int>(static_cast<unsigned char>(x[0]))
数字0x89是十进制的137。它超过了127的上限,现在是一个负数,因此您可以在那里看到FFFFFF。只需在int cast之后插入无符号字符即可。您将获得所需的结果

-Sandip

十进制中的数字0x89是137。它超过了127的上限,现在是一个负数,因此您可以在那里看到FFFFFF。只需在int cast之后插入无符号字符即可。您将获得所需的结果


-Sandip

z的定义在哪里?好的,我现在在编辑中看到了。永远不要使用隐式强制转换!静态施法不会产生任何效果difference@Gerhard:那么,如果强制转换是我应该回答的错误而不是注释的错误,那么无论如何,您不应该使用隐式强制转换@基里安人:没有隐式演员阵容。铸造总是明确的。有隐式转换,但这里不是这样。你可能在谈论C风格的演员阵容。z的定义在哪里?好的,我现在在编辑中看到了。永远不要使用隐式强制转换!静态施法不会产生任何效果difference@Gerhard:那么,如果强制转换是我应该回答的错误而不是注释的错误,那么无论如何,您不应该使用隐式强制转换@基里安人:没有隐式演员阵容。铸造总是明确的。有隐式转换,但这里不是这样。您可能正在谈论C样式转换。请记住,字符是有符号的还是无符号的是实现定义的。+1:但是如果默认字符类型是有符号的还是无符号的,则取决于实现。这也是我的想法。我刚刚测试了它,结果是0x79是正确的,但随后是FFFFFF XX。@danishgoel这是因为没有设置任何具有最高位的无符号字符,也就是说,记住字符是有符号的还是无符号的是实现定义的。+1:但是如果默认字符类型是有符号的还是无符号的,则取决于实现我也这么想。我刚刚测试了它,结果显示0x79是正确的,但随后是FFFFFF XX。@danishgoel这是因为没有设置最高位的无符号字符,即0x76,不应该也不会变为负数。尽管与您的观点无关,但基本字符串是未定义的行为。很多VC++和g++的实现,至少定义了它,但不一定以相同的方式。@JamesKanze:为什么基本字符串是未定义的行为?因为标准没有为它定义任何行为。基本字符串实际上是基本字符串。该标准只定义并要求C++03中的char和wchar__t进行专门化——为C++11添加char16_t和char32_t。实现可以为char_traits的通用版本提供定义,或者为unsigned char提供专门化,或者两者都不提供;在前两种情况下,它可以定义它
不管它喜欢什么。如果需要无符号字符的字符串,必须自己定义一个traits类。@JamesKanze:。如果需要无符号字符的字符串,必须自己定义一个traits类。除非实现没有定义它,对吗?如果实现没有定义它,那么它不会给出编译错误,因为它会尝试实例化未定义的char\u traits。0x76不应该也不会变为负值。此外,尽管与您的观点无关,但basic\u string是未定义的行为。很多VC++和g++的实现,至少定义了它,但不一定以相同的方式。@JamesKanze:为什么基本字符串是未定义的行为?因为标准没有为它定义任何行为。基本字符串实际上是基本字符串。该标准只定义并要求C++03中的char和wchar__t进行专门化——为C++11添加char16_t和char32_t。实现可以为char_traits的通用版本提供定义,或者为unsigned char提供专门化,或者两者都不提供;在前两种情况下,它可以随意定义它。如果需要无符号字符的字符串,必须自己定义一个traits类。@JamesKanze:。如果需要无符号字符的字符串,必须自己定义一个traits类。除非实现没有定义它,对吗?如果实现没有定义它,那么它不会给出编译错误,因为它会尝试实例化未定义的char_特征。