1.3 字符和字符串
扫码看视频
字符变量用于存放单个字符,用单引号标注,例如 'a'、'x'、 '?'、 '$'等。
字符串变量用于存放任意多个字符,用双引号标注,例如"Hello,world!"、"a" 、"$34567"等。
每一个字符串的结尾有一个“字符串结束标志”,以便系统判断字符串是否结束。C++语言规定以字符'\0'作为字符串结束的标志,'\0'占1字节。例如,如图1.17所示,字符串"Hello"的实际存储空间不是5字节,而是6字节,最后一个字节为'\0'。但'\0'是隐含的,输出时不会输出'\0',赋值时也不必手动加'\0',这些系统会自动进行后台处理。
图1.17
字符变量的使用很简单,参考例程如下所示。
1 //字符变量的使用
2 #include <bits/stdc++.h>
3 using namespace std;
4
5 int main()
6 {
7 char a='A',b='B',c,d; //定义字符变量a、b、c、d,a和b已赋值为'A'和'B'
8 cin>>c>>d; //从键盘输入c和d的值
9 cout<<a<<' '<<b<<' '<<c<<' '<<d<<'\n';//输出,字符间以一个空格间隔
10 return 0;
11 }
不要将字符变量和字符串变量混淆,例如,char c="a"这种把字符串"a"赋给只能容纳一个字符的字符变量c的语句是错误的,因为字符串"a"实际包含两个字符'a'和'\0'。
1.3.1 字符金字塔(Pyramid)
【题目描述】
试编程输入一个字符,用该字符构造一个高度为3的字符金字塔。例如,输入字符为“*”,则输出的字符金字塔如下。
*
* * *
* * * * *
【输入格式】
用键盘输入一个字符。
【输出格式】
输出用该字符构造的一个高度为3的字符金字塔,第1行行首有4个空格,第2行行首有2个空格,第3行行首无空格,非空格的字符间以一个空格间隔,行末无多余空格。
【输入样例】
*
【输出样例】
*
* * *
* * * * *
英文字母、数字以及一些常用的符号(例如*、#、@等)在计算机中是使用二进制数来表示的。具体用哪些二进制数表示哪个符号,每个人都可以约定自己的一套编码规则,但如果想互相通信而不造成混乱,就必须使用相同的编码规则。美国国家标准协会(American National Standards Institute,ANSI)出台了美国信息交换标准代码(American Standard Code for Information Interchange, ASCII),统一规定了上述常用符号用哪些二进制数来表示。
ASCII对照表请参见本书的附录部分。表1.4中列出了几个常用的码表值。
表1.4
字符在内存中以该字符相对应的ASCII值存储,它的存储形式与整数的存储形式类似,这样使得字符型数据和整型数据可以通用。一个字符既可以以字符形式输出,也可以以整数形式输出,还可以对它们进行算术运算。
下面的程序演示了字符变量与整数之间的通用性。
1 //字符变量与整数的通用性演示
2 #include <bits/stdc++.h>
3 using namespace std;
4
5 int main()
6 {
7 char c1,c2;
8 c1=65; //此处用数字而不是字符赋值
9 c2=66; //此处用数字而不是字符赋值
10 cout<<c1<<" "<<c2<<endl; //因为c1、c2为字符类型,所以默认输出字符
11 cout<<int(c1)<<" "<<int(c2)<<'\n'; //int()表示强制转换为整数
12 return 0;
13 }
输出结果如图1.18所示。
图1.18
程序中的第11行使用int(c1)将字符c1强制转换为整数。C++可以利用强制类型转换运算符将表达式转换成所需的类型,例如:
cout<<int(3.84); //将浮点数3.84强制转换为整数,故舍去小数部分,输出整数3
cout<<fixed<<double(10);//将整数10强制转换为浮点数10.0000输出
C++有两种转换,一种是系统自动进行的类型转换,例如3+3.4的结果是浮点数;另一种是强制类型转换。当系统自动进行的类型转换不能实现目的时,可以用强制类型转换。例如,取模运算符"%"要求其两侧均为整数,若x为浮点数,则x%3不合法,必须用int(x)%3进行转换。由于强制类型转换运算符优先级高于"%"运算符,因此先强制转换浮点数x为整数,再进行取模运算。
1.3.2 ASCII值转字符(ASCII1)
【题目描述】
输入一个整数,然后输出对应的字符。
【输入格式】
输入一个整数(保证整数存在对应的可见字符)。
【输出格式】
输出对应的字符。
【输入样例】
65
【输出样例】
A
1.3.3 小写字母转大写字母
【题目描述】
下面的程序实现了小写字母转对应的大写字母。
1 //小写字母转大写字母
2 #include <bits/stdc++.h>
3 using namespace std;
4
5 int main()
6 {
7 char c1,c2;
8 c1='a'; //c1赋值为小写字母'a'
9 c2='b'; //c2赋值为小写字母'b'
10 c1=c1-32; //小写字母比对应的大写字母的ASCII值大32
11 c2=c2-32;
12 cout<<c1<<" "<<c2<<'\n';//输出大写字母:A B
13 return 0;
14 }
从附录的ASCII对照表可以看出,每一个小写字母比它对应的大写字母的ASCII值大32。C++语言允许字符数据与整数直接进行算术运算,这种处理方法增大了程序的自由度,对字符做各种转换比较方便。
1.3.4 大写字母转小写字母(ASCII2)
【题目描述】
试编程使用cin语句输入3个大写字母,并将之转换为对应的小写字母输出。
【输入格式】
输入3个大写字母,字母间以一个空格间隔。
【输出格式】
输出3个对应的小写字母,字母间以一个空格间隔,行末无空格,有换行。
【输入样例】
A B C
【输出样例】
a b c
1.3.5 恺撒加密术
【题目描述】
“恺撒加密术”是一种替代密码的加密技术。如图1.19所示,对于信件中的每个字母,会用它后面的第t个字母代替。例如当t=4时,“China”加密的规则是用原来字母后面的第4个字母代替原来的字母,即字母“A”后面的第4个字母是“E”,用“E”代替“A”。因此,“China”应加密为“Glmre”。请编写程序将任意5个字符加密(暂不考虑替代的字母跳过“界”的问题)。
图1.19
1 //恺撒加密术
2 #include <bits/stdc++.h>
3 using namespace std;
4
5 int main()
6 {
7 char c1='C',c2='h',c3='i',c4='n',c5='a';//此处也可换成其他英文字母
8 c1+=4; //c1+=4即c1=c1+4,这种写法更简洁
9 c2+=4;
10 c3+=4;
11 c4+=4;
12 c5+=4;
13 cout<<c1<<c2<<c3<<c4<<c5<<endl;
14 return 0;
15 }
在运算符“=”之前加上其他运算符,称为复合运算符,例如:
a+=3;∥等价于a=a+3
x%=3;∥等价于x=x%3
如果是包含若干项的表达式,则相当于它有圆括号,例如x%=y+4
相当于x%=(y+4)
,即x=x%(y+4)
而不是x=x%y+4
。
1.3.6 改进的加密术(encryption)
【题目描述】
请编写一个程序,使用cin语句输入任意5个英文字符和任意一个值t(-8<t<8),则原先的5个英文字符将分别用其后面的第t个英文字符代替并输出(暂不考虑替代的字符跳过“界”的问题)。
【输入格式】
第1行输入5个英文字符,字符间以空格间隔。
第2行输入1个整数t。
【输出格式】
输出加密后的英文字符,字符间无须空格间隔。
【输入样例】
C h i n a
4
【输出样例】
Glmre
参考伪代码如下所示,请根据伪代码的思路编写C++程序完成本题。
1 定义5个字符变量
2 定义t
3 输入5个字符变量的值
4 输入t的值
5 5个字符依次以其后面的第t个字符代替
6 输出5个加密后的字符
C++还允许一种特殊形式的字符常量,就是以“\”开头的字符序列。例如前面已经用过的'\n',它代表换行符。这是一种“控制字符”,是不能在显示器上显示的,在程序中也无法用一般形式的字符表示,只能采用特殊形式的字符表示。
以“\”开头的常用特殊字符(转义字符)如表1.5所示。
表1.5
通过转义字符,就可以输出诸如“\”“'”“"”之类的字符了。
例如要输出“\”,代码应该为cout<<“\\”。
1.3.7 输出特殊字符(special)
【题目描述】
请输出图1.20所示的字符串,注意所有的字符均为英文半角形式。
图1.20
【输入格式】
无输入。
【输出格式】
见输出样例,注意除单词之间以一个空格间隔外,无任何多余空格,以换行结束。
【输入样例】
无。
【输出样例】
He said:"The symbol is '\'."
为了更好地处理字符串,C++提供了string类,它提供了添加、删除、插入和查找等丰富的操作方法。
string类的部分操作方法如下所示。
1 //string类的部分操作方法
2 #include <bits/stdc++.h>
3 using namespace std;
4
5 int main()
6 {
7 string s="Hi,..morn"; //定义了名为s的string类并初始化
8 s=s+"ing"; //尾部添加字符串"ing"
9 cout<<"添加字符串:"<<s<<endl; //输出"Hi,..morning"
10 s.erase(3,2); //删除第3个字符后的2个字符
11 cout<<"删除字符串:"<<s<<endl; //输出"Hi,morning"
12 int f=s.find("Hi,"); //查找"Hi,"在s中的位置,-1为无法找到
13 s.insert(f+3,2,'G'); //在第3个字符后插入单个字符'G'2次
14 cout<<"插入两字符:"<<s<<endl; //输出"Hi,GGmorning"
15 s.insert(5,",MM,"); //在第5个字符后插入字符串",MM,"
16 cout<<"插入字符串:"<<s<<endl; //输出”Hi,GG,MM,morning”
17 string v=s.substr(4,3); //取s中第4个字符后的3个字符给v
18 cout<<"字符串子串:"<<v<<endl; //输出"G,M"
19 cout<<"string长度:"<<v.length(); //输出3,即v的长度
20 return 0;
21 }
输出结果如图1.21所示。
图1.21
1.3.8 费解的对话(chat)
【题目描述】
宠物机器人的单词库被病毒感染了,第一种感染方式是圆括号内的内容没有被破坏,但是圆括号外面加入了一些奇怪的数字,例如“(Mary)”变成了“253(Mary)5”;第二种感染方式是在单词中加了一个“...”子串,例如“hello”变成了“he…llo”。请修复它。
使用“内容市场”App扫描看视频
【输入格式】
输入两行字符串(字符串中无空格)。第一行是被第一种感染方式感染的字符串,第二行是被第二种感染方式感染的字符串。
【输出格式】
输出一行对应的正确字符串,两个字符串间以逗号间隔。
【输入样例】
23453(Mary)24565
mor…ning
【输出样例】
Mary,morning