一维字符数组¶
字符串可以用一维字符数组表示,也可以用 string 表示。
前者是 C 风格的字符串,后者是 C++ 风格的字符串。
一维字符数组¶
定义
初始化
这两种初始化的方法,存储到字符数组中的格式是完全一致的。
下面是数组中的存储内容
字符数组存入相应的字符后,自动在末尾添加一个特殊字符 '\0'
,作为字符串的结束标记。
'\0'
对应的 ASCII 码为 0。
输入输出
使用 cin, cout
使用 scanf(), printf()
访问
遍历
基础操作
int len = strlen(s); // 获取字符串的长度
int p = strcmp(s1, s2); // 判断 s1, s2 是否相等。相等是 0,小于是负数,大于是正数
strcat(s1, s2); // s1 后面拼接上 s2
strcpy(s1, s2); // s2 复制给 s1,s1 存的东西变成和 s2 一样
memcpy(s1, s2, sizeof s1); // 把 s2 的值赋值给 s1
关于以
'\0'
结尾的讨论
从下面两个计算机实验中,我们可以得到这样的结论:
\0
不占字符串的长度,但占用字符串的存储空间。
string¶
在标准模板库 STL 中,建立了有关字符串操作的 string 类。
定义
初始化
输入输出
访问
遍历
基础操作
s1 = s; // 复制操作
s += "def"; // 拼接字符串
s += 'g'; // 拼接字符
if (s == "zq") // 判断是否相等
if (s < "ab") // 按字典序比大小关系
// 截取子串
cout << s.substr(1, 2); // 从下标为1那个位置,截取长度为2的子串
cout << s.substr(1); // 从下标为1那个位置,截取右边的所有内容
// 插入子串
s.insert(1, "xxx"); // 在下标为1那个位置,插入一个字符串"xxx"
// 替换子串
s.replace(1, 2, "xxx"); // 将从下标1开始,长度为2的子串,替换为"xxx"
// 查找子串、查找字符,返回第一次出现的位置,不存在返回 string::npos(一般理解为-1)
// 常用于判断一个字符串是否为另一个字符串的子串
s.find("zq"); // 查找子串zq第一次出现的位置
s.find('q'); // 查找字符q第一次出现的位置
if (s.find("zq") == string::npos) cout << "Not find"; // 如果没找到
s.find("zq", p); // 从下标p那个位置往后找"zq"第一次出现的位置
// 这个操作通常用来向右,找到一个替换一个,循环迭代向右替换
// 直到都替换完了,结束
string s = "zqoizqoizqoizqoizqoizqoizqoi";
int p = 0;
while (s.find("zq", p) != string::npos) {
p = s.find("zq", p);
s.replace(p, 2, "NB");
}
cout << s;
// 翻转字符串
reverse(s.begin(), s.end());
string 的长度和占用存储空间的问题
从下面三个实例中,我们可以得到这样的结论:
.size()
表示字符串的长度,sizeof
表示占用存储空间都是 32 字节。
统计字符¶
一个由大小写字母、数字组成的字符串,
统计26个大写字母、26个小写字母、10个数字字符出现的次数
int cntA[30], cnta[30], cnt[15];
int main() {
string s;
cin >> s;
for (auto c : s) {
if (c >= 'A' && c <= 'Z') cntA[c - 'A']++;
if (c >= 'a' && c <= 'z') cnta[c - 'a']++;
if (c >= '0' && c <= '9') cnt[c - '0']++;
}
}
大小写转换¶
输入一个字符串,全部转换为小写字母
for (int i = 0, len = s.size(); i < len; i++)
if (s[i] >= 'A' && s[i] <= 'Z') s[i] += 32;
cout << s;
统计字符串¶
前文对字符进行了统计,可以用字符进行存储,原理是用字符 ASCII 码相对距离作为数组的下标,存储起来。
对于字符串,那怎么表示呢?
在这里,我们需要使用到标准模板库 STL 当中的 map
。
int main() {
int n;
string s;
map<string, int> mp;
while (n--) {
cin >> s;
mp[s]++:
}
for (auto i : mp) cout << i.first << ' ' << i.second << endl; // 输出每个字符串出现了几次
return 0;
}
读入一整行¶
使用
getline()
。
cin
读入到空格、换行、EOF(文件终止符) 的时候,会终止读入。
如果我们想把一整行,把空格字符当成字符串的一部分读入,使用 getline()
。
getline()
会读入一整行,但当我们不需要读入空格时候,我们正常使用 cin
。
注意,不要滥用 getline()
。
过滤空格
我们通过 getline()
读入一整行,把其中的空格过滤掉。