C++中+=运算符向字符串添加意外ff字节的问题及解决
C++ string += 128后输出异常的修复方案
问题代码
#include<iostream> void test(string in){ for(short i=0; i<in.length(); i++) cout<<hex<<(unsigned short)in[i]; cout<<"\n"; string msg=in; for(short i=0; i<msg.length(); i++) cout<<hex<<(unsigned short)msg[i]; cout<<"\n"; msg+=(char)128; for(short i=0; i<msg.length(); i++) cout<<hex<<(unsigned short)msg[i]; } int main(){ test("123456"); }
预期输出
313233343536 313233343536 31323334353680
实际输出
313233343536 313233343536 313233343536ff80
问题原因
你的编译器默认将char视为有符号类型(signed char),取值范围为-128到127。当把128赋值给signed char时,数值超出范围发生溢出,实际存储的是补码形式的-128(二进制10000000)。
将这个signed char强制转换为unsigned short时,会触发符号扩展:由于原类型是有符号的,系统会把最高位的1填充到扩展出的高位字节,导致-128(0x80)被扩展为0xFF80,这就是输出中出现ff80的原因。
修复方案
方案一:使用无符号字符赋值
修改赋值语句,直接用unsigned char存储128:
msg += static_cast<unsigned char>(128);
128会以无符号形式存入字符串,转换为unsigned short时不会触发符号扩展,输出即为80。
方案二:转换时先转无符号字符
保持赋值语句不变,修改输出时的强制转换逻辑,先将char转为unsigned char再扩展为unsigned short:
cout << hex << static_cast<unsigned short>(static_cast<unsigned char>(msg[i]));
此方法会跳过符号扩展步骤,确保高位不会被填充1。
方案三:全局设置char为无符号类型
在Code::Blocks中,给编译器添加-funsigned-char编译选项,让默认char变为无符号类型:
- 点击菜单栏「Settings」→「Compiler」
- 切换到「Compiler settings」→「Other options」
- 添加
-funsigned-char选项,点击确定后重新编译项目。
内容的提问来源于stack exchange,提问作者Ágoston Kis
相关产品推荐
相关产品推荐

