+= 运算符在 C++ 中向字符串添加意外的 ‘ff’ 字节。

huangapple go评论65阅读模式
英文:

+= operator adding unexpected 'ff' byte to string in c++

问题

Here's the translated code part:

我有这段代码:
```cpp
#include <iostream>
void test(std::string in) {
    for (short i = 0; i < in.length(); i++)
        std::cout << std::hex << (unsigned short)in[i];
    std::cout << "\n";
    std::string msg = in;
    for (short i = 0; i < msg.length(); i++)
        std::cout << std::hex << (unsigned short)msg[i];
    std::cout << "\n";
    msg += (char)128;
    for (short i = 0; i < msg.length(); i++)
        std::cout << std::hex << (unsigned short)msg[i];
}
int main() {
    test("123456");
}

我期望的输出是:

313233343536
313233343536
31323334353680

但实际输出如下:

313233343536
313233343536
313233343536ff80

很明显,+= 运算符做了我没有考虑到的事情。我在一台64位机器上使用Code::Blocks。我应该如何修复它?

英文:

I have this code:

#include&lt;iostream&gt;
void test(string in){
	for(short i=0; i&lt;in.length(); i++)
		cout&lt;&lt;hex&lt;&lt;(unsigned short)in[i];
	cout&lt;&lt;&quot;\n&quot;;
	string msg=in;
	for(short i=0; i&lt;msg.length(); i++)
		cout&lt;&lt;hex&lt;&lt;(unsigned short)msg[i];
	cout&lt;&lt;&quot;\n&quot;;
	msg+=(char)128;
	for(short i=0; i&lt;msg.length(); i++)
		cout&lt;&lt;hex&lt;&lt;(unsigned short)msg[i];
}
int main(){
	test(&quot;123456&quot;);
}

I expect the output to be:

313233343536
313233343536
31323334353680

But instead, it is the following:

313233343536
313233343536
313233343536ff80

It's clear that the += operator does something that i didn't count with. I use Code::Blocks on a 64-bit machine. How can I fix it?

答案1

得分: 4

Your compiler uses a signed char type, which has a value range of [-128, 127].

msg+=(char)128;

This line adds a character with a value of -128, represented in binary as 0b1000'0000.

When you read this character in (unsigned short)msg[i], it undergoes a promotion, padding the value with 1 bits until the width of the target type is reached. Then, the conversion to unsigned short occurs, resulting in 0b1111'1111'1000'0000, which is equivalent to 0xff80.

To resolve this, you can cast to unsigned char first:

for (short i = 0; i < msg.length(); i++)
    cout << hex << static_cast<unsigned short>(static_cast<unsigned char>(msg[i]));
英文:

Your compiler uses an signed char type, i.e. the range of values is [-128, 127].

msg+=(char)128;

adds a char with value -128 which is represented binary 0b1000&#39;0000.

When you read this char in (unsigned short)msg[i], the value first undergoes a promotion padding the value with 1 bits until the width of the target type is reached and then the conversion to unsigned short happens leaving you with (0b1111&#39;1111&#39;1000&#39;0000 = 0xff80)

0b1111&#39;1111&#39;1000&#39;0000
  ^^^^ ^^^^           bits from sign extension
            ^^^^ ^^^^ 128

To fix this you can cast to unsigned char first:

for (short i = 0; i &lt; msg.length(); i++)
    cout &lt;&lt; hex &lt;&lt; static_cast&lt;unsigned short&gt;(static_cast&lt;unsigned char&gt;(msg[i]));

huangapple
  • 本文由 发表于 2023年5月26日 17:13:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/76339343.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定