字符数组与字符串
定义
字符型
用于表示单个字符 只占用1个字节,将对应的ASCII码放入存储单元
语法:char ch = 'a'
需要注意:
1.要用单引号将字符括起来
2.单引号内只能有一个字符,不可以是字符串
字符串型
用于表示一串字符
两种风格:
- C风格字符串:
char
变量名[] = “字符串值” 要用双引号 - C++风格字符串:
string
变量名 = “字符串值” 需要加入头文件#include<string>
转义字符
用于表示一些不能显示出来的ASCII字符
常用的转义字符:/n 换行,将当前位置移到下一行开头
/t 水平制表,跳到下一个TAB位置,/t和其前面的内容一共占8个字符
// 代表一个反斜杠字符
初始化与赋值
只可以在数组定义并初始化的时候才可以使用字符串字面值对字符数组初始化,一定要注意字符串字面值的结尾处还有一个空字符。不能用赋值语句将一个字符串常量或字符数组直接赋给另一个数组。
1 | char a1[] = {'C', '+', '+'}; //列表初始化,没有空字符 |
字符/字符数组/字符串的输入与输出
一个字符的输入
直接用cin
输入字符。
cin
这一输入操作,遇到结束符(Space, Tab, Enter)就会结束,且对于结束符,并不保存到变量中,但最后一个Enter会在缓冲区。
1 |
|
用cin.get()
函数输入
可以用于读入一个字符;有2中形式:
无参数cin.get()
,可用于舍弃输入流中的不需要的字符,或者舍弃回车,弥补三参数的cin.get(ch, 10, '/n')
的不足。
1 | char c; |
一个参数cin.get(char)
1 | char c; |
要注意的是,cin.get()
遇到结束符停止读取,但并不会将结束符从缓冲区丢弃。
1 | char ch1,ch2; |
输入a[Enter],读取到结束符'/n'
,其仍在缓冲区中被存入ch2
,在输出a之后,第二次输出'/n'
即换行,而输出的第二个ASCII码值为10,即'/n'
的ASCII值,说明cin.get()
遇到结束符并不会将之删除。
用getchar()
输入字符
1 | char c; |
字符串的输入
直接用cin
输入字符
1 |
|
用cin.get()
函数输入
有三个参数的cin.get()
函数:cin.get(ch, 10, '/n')
读取10-1(10减1=9,最后一个为'/0'
)个字符(包括空格),赋给指定的字符数组,;如果在读取9个字符之前,遇到指定的终止字符'/n'
,则提前结束读取(如果第3个参数没有指定,则默认为'/n'
),而结束符仍在缓冲区中;读取成功返回非0值(真),如失败(遇到文件结束符)则返回0值(假)。
还要一点要注意,cin.get(ch, 10, '/n')
,当第一个输入字符为结束符时,缓冲区将无该结束符。
1 |
|
输入:we are good friends[Enter],由于遇到结束符 'o'
,首先读入we are g到ch1
,此时ood friends仍在缓冲区,当执行cin.get(ch2,10)
会直接从缓冲区读入ood frien(只能读入9个字符),而不需要申请从键盘输入。
用cin.getline()
函数输入
用法与上面的cin.get()
类似,但也有区别:
cin.get()
当输入的字符串在结束符之前的长度超过接收长度时,不会引起cin
函数的错误,剩余的字符会留在缓冲区,后面若有cin
操作,会继续从缓冲区读取;当cin.getline()
输入超长时,会引起cin
函数的错误,后面的cin
操作将不再执行。
cin.get()
每次读取一整行并把由Enter
键生成的换行符'/n'
留在输入队列中,然而cin.getline()
每次读取一整行并把由Enter
键生成的换行符抛弃。
cin.get()
遇到结束符是停止读取,缓冲区指针不移动;cin.getline()
遇到结束符时,缓冲区指针移到终止标志字符之后。
1 | char ch1[20],ch2[20]; |
一个需要注意的地方:cin
这一输入操作,遇到结束符(Space, Tab, Enter)就会结束,且对于结束符,并不保存到变量中,但最后一个Enter会在缓冲区。而无参数cin.get()
,可用于舍弃输入流中的不需要的字符,或者舍弃回车,弥补三参数的cin.get(ch, 10, '/n')
的不足。
1 |
|
1 |
|
字符串的输出
用cout
输出字符数组
1 |
|
需要注意的是,cout
输出有终止条件(一般是碰到'\0'
),当用字面值初始化字符数组时,会自动在串尾加上'\0'
;当用列表初始化字符数组时,若不在串尾加上’\0’,用cout
输出时就不知道何时停止,可能读到内存里其他随机的位置,显示就会在字符串后面出现乱码。
1 | char a[8] = { 'C','o','m','p','u','t','e','r' }; |
例子
1.字符串加密:输入一个字符串,把每个字符变成它后续字符,如果是’Z’或者’z’,则对应变成’A’或者’a’,空格则不变。然后将变换后的字符串输出;要求能够接受连续输入。
1 |
|
2.字符串连接:输入两个字符串,将其中较短的串接到较长的串的后面。不使用系统函数strcat
,每个输入的串的长度不超过20。
1 |
|
3.统计单词数:输入一个英文句子(不超过80个字母),统计其中有多少个单词,单词之间用空格分开。
1 |
|
当输入不是很严格时,比如有数字,或输入不规范,比如标号后不加空格等等,上面的程序会多算单词数。可以改成如下的程序,直接判断是不是字母。
1 |
|
对于
char
数组char s[100]
,要读入一整行可以用cin.getline(s, 100)
;,或者fgets(s, 100, stdin);
要输出可以用
printf("%s\n", s);
,等价于puts(s);
char
数组常用的函数有(要引入头文件#include<string.h>
):
strlen(str)
,求字符串的长度('\0'
不计入其中);strcmp(a, b)
,比较两个字符串的大小,a < b 返回-1,a == b 返回0,a > b返回1。这里的比较方式是字典序(字典序一般和贪心相关);strcpy(a, b)
,将字符串b复制给从a开始的字符数组。
C++标准库类型string
C++标准库类型string
字符串是可变长的字符序列,比字符数组更加好用。需要引入头文件#include<string>
,读入string
字符串可以用getline(cin, s);
读入一整行;使用cin >> s;
读入,遇到结束符(Space, Tab, Enter)就会终止。
定义和初始化:
1 |
|
string
的读写:(不能用printf
直接输出string
,需要写成:printf(“%s”, s.c_str());
)
1 |
|
常用函数 / 操作:
.empty()
用来判断字符串是否为空,返回一个布尔值;.size()
操作返回字符串的长度,其时间复杂度为$O(1)$(注意size
是无符号整数,因此s.size() <= -1
一定成立);string
的比较:直接使用关系符<, <=, >, >=, ==, !=
,按字典顺序比较;
1 |
|
- 为
string
对象赋值:s1 = s2;
,用s2的副本替换s1的副本; - 为
string
对象赋值:
1 | string s1(10, ‘c’), s2; // s1的内容是 cccccccccc;s2是一个空字符串 |
- 两个
string
对象相加:
1 | string s1 = “hello, ”, s2 = “world\n”; |
- 字面值和
string
对象相加:做加法运算时,字面值和字符都会被转化成string
对象,因此直接相加就是将这些字面值串联起来;当把string
对象和字符字面值及字符串字面值混在一条语句中使用时,必须确保每个加法运算符的两侧的运算对象至少有一个是string
。
1 | string s1 = “hello”, s2 = “world”; // 在s1和s2中都没有标点符号 |
处理string
对象中的字符 :
- 可以将
string
对象当成字符数组来处理:
1 | string s = "hello world"; |
- 或者使用基于范围的
for
语句:
1 | string s = "hello world"; |