int main()
{
string s;
cout << "enter the string :" << endl;
cin >> s;
for (int i = 0; i < s.length(); i++)
s[i] ^= 32;
cout << "modified string is : " << s << endl;
return 0;
}
我看到这个代码在stackoverflow上将大写转换为小写。
但我不明白行s[i] = s[i]^32
。
它是如何运作的?
答案 0 :(得分:20)
^=
是exclusive-or赋值运算符。 32是二进制100000,因此^= 32
切换目标中的第五位。在ASCII中,小写和大写字母相隔32个位置,因此这会将较低的大写字母转换为大写字母,而另一种方式也是如此。
但它仅适用于ASCII,不适用于Unicode,仅适用于字母。要编写可移植的C ++,您不应该将字符编码假定为ASCII,因此请不要使用此类代码。 @πάνταῥεῖs答案显示了一种正确的方法。
答案 1 :(得分:16)
它是如何运作的?
让我们看一下ASCII值'A'
:
'A'
是二进制1000001
与32(二进制100000
)
产生任何值,其中上部字符表示位未设置:
1000001
XOR
100000
ASCII中的1100001
== 'a'
。
任何理智且可移植的c或c ++应用程序都应使用tolower()
:
int main()
{
string s;
cout<<"enter the string :"<<endl;
cin>>s;
for (int i=0;i<s.length();i++) s[i] = tolower( (unsigned char)s[i] );
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
cout<<"modified string is : "<<s<<endl;
return 0;
}
s[i]=s[i]^32
(货物崇拜)魔术,依赖于ASCII table特定的数字char
值映射。
还有其他char
代码表,例如EBCDIC
s[i]=s[i]^32
方法很难找回相应的小写字母。
std::ctype::tolower()
的参考文档页面中显示了转换为小写字符的更复杂的c ++版本。
答案 2 :(得分:5)
在C ++中,与其前身C一样,char
是一种数字类型。毕竟这是在硬件上表示字符的方式,而这些语言并不是隐藏起来的。
在ASCII中,字母具有有用的属性,即大写和小写字母之间的差异是单个二进制位:第5位(如果我们从0开始从右开始编号)。
大写字母A由字节0b01000001
(十六进制为0x41
)表示,小写字母a由字节0b01100001
(十六进制为0x61
)表示。请注意,大写和小写A之间的唯一区别是第五位。这种模式从B到Z继续。
所以,当你在一个代表ASCII字符的数字上^= 32
(顺便提一下,是2到5次方)时,它做的是切换第5位 - 如果是0,它就变成1,反之亦然,它将字符从大写改为小写,反之亦然。