大小写转换的问题
我刚开始学c语言时, 只知道大写字母转小写字母+32
,小写字母转大写字母-32
:
char ch1 = 'A';
char ch2 = 'b';
//把ch1转换为小写:
ch1 += 32;
//把ch2转换为大写:
ch2 -= 32;
今天学了一点ACSII码后, 懂了一点其他方法:计算机中所有的信息都是2进制, 我们要把如"desk", "123"这些信息存储再计算机中, 就要对其进行编码, 将其转换为2进制信息进行存储. ASCII码就是其中一种编码方案
我们可以将所有的字母的大写字符和小写字符所对应的ASCII码列出来, 进行对比, 从中找到规律:
字母 | 10进制 | 16进制 | 2进制 | |
---|---|---|---|---|
大写 | A | 65 | 41 | 01000001 |
小写 | a | 97 | 61 | 01100001 |
大写 | B | 66 | 42 | 01000010 |
小写 | b | 98 | 62 | 01100010 |
大写 | C | 67 | 43 | 01000011 |
小写 | c | 99 | 63 | 01100011 |
观察以后发现, 我们可以对小写字母减32(10进制), 或减20H(16进制), 或减100000B(2进制); 大写字母转小写字母则加上32(10进制), 或加20H(16进制), 或加100000B(2进制);
下面考虑这样一个问题:将"BaSiC"中的小写字母转为大写, 大写字母不做改变; 将"iNfOrMaTiOn"中的大写字母转为小写, 小写字母不做改变.
其中一种方法就是判断每一个字母是大写还是小写, 这样比较麻烦.
我们应该重新观察, 寻找新的规律。可以看出,就ASCⅡ码的二进制形式来看,除第
5位(位数从0开始计算)外,大写字母和小写字母的其他各位都一样。大写字母ASCⅡ码的第5位为0,小写字母的第5位为1。这样,我们就有了新的方法,一个字母,不管它原来是大写还是小写,将它的第5位置0,它就必将变为大写字母;将它的第5位置1它就必将变为小写字母。在这个方法中,我们不需要在处理前判断字母的大小写。
对于“BaSiC”中的“B”,按要求,它已经是大写字母了,不应进行改变,将它的第5位设为0,它还是大写字母,因为它的第5位本来就是0.
用什么方法将一个数据中的某一位置的0 ?可以用按位与&
和按位或|
:
A的二进制为: 01000001
a的二进制为: 01100001
根据&
的运算规则, 01000001(A) | 00100000 = 01100001(a)
同理 01100001(a) & 11011111 = 01000001(A)
于是:
#include <iostream>
#include <string>
using namespace std;
void test2() {
string str1 = "BaSic";
string str2 = "iNfOrMaTiOn";
for(auto &c: str1) {
c &= 0b11011111; //0b为2进制的前缀,将字符c的的第5位(位数从0开始计算)置为0, 变成大写字母
}
for(auto &c: str2) {
c |= 0b00100000; //将字符c的的第5位(位数从0开始计算)置为1, 变成小写字母
}
cout << "---------------------\n";
cout << str1 << endl;
cout << str2 << endl;
}
int main(){
test2();
return 0;
}
输出结果为:
BASIC
information