C++ 提供的字符串形式:
起源:C 语言
实质:使用 null 字符 \0
终止的一维字符数组。一个以 null 结尾的字符串,包含了组成字符串的字符。
char site[5]={'y','u','y','a','\0'};
//字符数组的大小比 yuya 的字符数多一个
char site[5]="yuya";
不需要把 null 字符放在字符串常量末尾,因为 C++ 编译器会在初始化数组时,自动把\0
放在字符串的末尾
头文件:string
,使用时必须包含
string 定义在命名空间 std 中
#include
using std::string;
string s1;
默认初始化,s1 是一个空字符串
string s2(s1);
s2 是 s1 的副本
string s2=s1;
等价于 s2(s1),s2 是 s1 的副本
string s3("yuya");
s3 是字面值 "yuya" 的副本,除了字面值最后的那个空字符外
string s3="yuya";
等价于 s3("yuya"),s3 是字面值 "yuya" 的副本
string s4(n,'c');
把 s4 初始化为由连续 n 个字符 c 组成的串
os<
将 s 写到输出流 os 中,返回 os
is>>s
从 is 中读取字符串赋给 s,字符串以空白分隔,返回 is
getline(is,s)
从 is 中读取一行赋给 s,返回 is
s.empty()
s 为空返回 true,否则返回 false
s.size()
返回 s 中字符的个数
s[n]
返回 s 中第 n+1 个字符的引用,位置 n 从 0 计起
s1+s2
返回 s1 和 s2 连接后的结果
s1=s2
用 s2 的副本代替 s1 中原来的字符
s1==s2
如果 s1 和 s2 中所含的字符完全一样,则它们相等;string 对象的相等性判断对字母的大小写不敏感
s1!=s2
<,<=,>,>=
利用字符在字典中的顺序进行比较,且对字母的大小写不敏感
string s;
cin>>s;
cout<
执行读取操作时,string 对象会自动忽略开头的空白(即空格符、换行符、制表符等)并从第一个真正的字符开始读起,直到遇见下一处空白为止
while(cin>>word) 反复读取,直至到达文件末尾
cout< 重复若干次之后,一旦遇到文件结束标记或非法输入循环结束 使用 getline 代替 >> ,可以在最终得到的字符串中保留输入时的空白符 参数:一个输入流,一个 string 对象 函数从给定的输入流中读入内容,直到遇到换行符为止,此时,换行符也被读进来,把所读的内容存入到 string 对象中,此时不存换行符。getline 只要遇到换行符就结束读取操作并返回结果,哪怕是一开始就是换行符也是如此,此时所得的结果是空 string【触发 getline 函数返回的换行符实际上被丢弃了,得到的 string 对象不包含该换行符】 getline 也会返回其参数流,故可以作为判断条件 string line; while(getline(cin,line)) cout< empty 函数根据 string 对象是否为空返回一个对应的布尔值 string line; while(getline(cin,line)) if(!line.empty()) 遇到空行直接跳过 cout< size 函数返回 string 对象的长度,即 string 对象中字符的个数 string line; while(getline(cin,line)) if(line.size()>80) 只输出字符个数超过80的行 cout< size 函数返回的是一个 string::size_type 类型的值,是一个无符号类型的值,能足够存放下任何 string 对象的大小。C++11 新标准中,允许编译器通过 auto 或者 decltype 推断变量的类型: size 函数返回一个无符号整型数,在表达式中混用带符号数和无符号数将会产生意想不到的结果,例如:假设 n 是一个具有负值的 int ,则表达式 等同于 size 对于 string 对象,允许把一个对象的值赋给另外一个对象 string st1(10,'c'),st2; st1=st2; //将 st2 的值赋给 st1,此时,二者均为空字符串 功能:清空字符串内容,变成一个空字符串 函数原型: 用法: 比较运算符逐一比较 string 对象中的字符,并且对大小写敏感 相等性运算符(==和!=)分别检验两个 string 对象相等或不相等,string 对象相等意味着其长度相同并且所包含的字符也全都相同 关系运算符 <、<=、>、>= 分别检验一个 string 对象是否小于、小于等于、大于、大于等于另外一个 string 对象 上述运算符都依照(大小写敏感的)字典顺序: string s1="Hello"; string s2="Hello World"; string s3="Hiya"; s3>s2>s1 两个 string 对象相加得到一个新的 string 对象,其内容是把左侧的运算对象与右侧的运算对象串接而成,前半部分是加号左侧 string 对象所含的字符,后半部分是加号右侧 string 对象所含的字符 string s1="hello, " , s2="world\n"; string s3=s1+s2; s1+=s2; //等价于s1=s1+s2 因为标准库允许把字符字面值和字符串字面值转换成 string 对象,所以在需要 string 对象的地方可以使用这两种字面值代替 string s1="hello" , s2="world"; string s3=s1+", "+s2+'\n'; 当把 string 对象和字符字面值及字符串字面值混在一条语句中使用时,必须确保每个加法运算符(+)的两侧的运算对象至少有一个是 string string s4=s1+", "; //正确 string s5="hello"+", "; //错误 string s6=s1+", "+"world"; //正确,string s6=(s1+", ")+"world"; 子表达式 s1+", " 的结果是一个 string 对象,作为第二个加号运算符的左侧运算对象,与string tmp=s1+", "; s6=tmp+"world"; 等价 string s7="hello"+", "+s2; //不能把字面值直接相加,string s7=("hello"+", ")+s2; 字符串字面值与 string 是不同的类型 string s; s+='a'; s.append('a'); 在第一个字符串中进行查找,返回第一个与指定字符串中任何字符都不匹配的元素的位置 函数原型: 功能:从字符串中获取想要的子串 参数:pos 想要获取的子字符串的第一个字符的位置,如果 pos=s.size() ,则返回一个空字符串,如果pos>s.sizr(),报错 【第一个字符的下标从 0 开始】 len 子串中所包含的字符数 返回值:目标对象 头文件:cctype 如果想要处理 string 对象中的每个字符,最好使用 C++11 新标准提供的 范围 for 语句,遍历给定序列中的每个元素并对序列中的每个值执行某种操作 语法形式: expression 是一个对象,用于表示一个序列 declaration 定义一个遍历,该变量将被用于访问序列中的基础元素 每次迭代,declaration 部分的变量会被初始化为 expression 部分的下一个元素值 string str("some string"); for(auto c : str) cout< 通过使用 auto 关键字【自动推断变量的类型】让编译器来决定变量 c 的类型,这里 c 的类型是 char //统计 string 对象中标点符号的个数 string s("Hello World!!!"); decltype(s.size()) punct_cnt=0; //punct_cnt 的类型与 s.size 的类型一样,auto 与 decltype 一样,都可以推断类型 for(auto c : s ) if(ispunct(c)) punct_cnt++; cout< 如果想要改变 string 对象中字符的值,必须把循环变量定义成引用类型。所谓引用只是给定对象的一个别名,因此当使用引用作为循环控制变量时,此变量实际上被依次绑定到了序列的每个元素上,使用这个引用,就能改变它绑定的字符 //转换成大写形式 string s("Hello World!!!"); for(auto &c : s) //c 是引用 c=toupper(c); //c 是一个引用,因此赋值语句将改变 s 中字符的值 访问 string 对象中的单个字符的方式: 下标运算符 [ ] 接收的输入参数是 string::size_type 类型的值,这个参数表示要访问的字符的位置,返回值是该位置上的字符的引用,下标从 0 计起,s[0] 是第一个字符,s[s.size()-1] 是最后一个字符 string 对象的下标必须大于等于0而小于 s.size() 任何表达式只要其值是一个整型值就能作为索引,如果索引是带符号类型的值将自动转换成由 string::size_type 表达的无符号类型 在访问指定字符之前,首先检查 s 是否为空,无论什么时候对 string 对象使用下标,都要确认该位置上确实有值,如果 s 为空,则 s[0] 的结果是未定义的 只要字符串不是常量,就可以为下标运算符返回的字符赋新值 string s("some string"); if(!s.empty()) s[0]=toupper(s[0]); //为 s 的第一个字符赋一个新值 //把 s 的第一个词改成大写形式 for(decltype(s.size()) index = 0 ; index != s.size() && !isspace(s[index]) ; ++index) s[index]=toupper(s[index]); 通过计算得到某个下标值,然后直接获取对应位置的字符 begin 和 endgetline
判断字符串是否为空
empty
长度
size
auto len=line.size();
len 的类型是 string::size_types.size()
length
赋值
清空
clear
str.clear();
删除字符
erase
string& erase(size_t pos = 0, size_t n = npos);
iterator erase(iterator position);
iterator erase(iterator first, iterator last);
erase(pos, n); //删除从pos开始的n个字符,比如erase(0, 1)就是删除第一个字符
erase(position); //删除从position处的一个字符(position是个string类型的迭代器)
erase(first, last); //删除从first到last之间的字符(first和last都是迭代器)
比较 string 对象
比较运算符
compare
s1.compare(s2); //直接比较s1和s2
s1.compare(pos,n,s2); //s1下标为pos的字符开始的n个字符构成的子串与s2进行比较
s1.compare(pos,n,s2,pos1,n1); //s1下标为pos的字符开始的n个字符构成的子串与s2下标为pos1的字符开始的n1个字符构成的子串进行比较
指定位置插入字符串
insert
s1.insert(pos,str); //在s1下标为pos的字符前插入字符串str
s1.insert(pos,str,pos1,n); //str从下标为pos1开始的n个字符插入s1下标为pos的字符前
s1.insert(pos,n,c); //在s1下标为pos的字符前插入n个字符c
拼接
string + string
字面值 + string
字符串末尾添加字符/字符串
append
s1.append(s2); //直接添加另外一个完整的字符串
s1.append(s2,pos,len); //添加s2的以pos为索引、长度为len的子串
s1.append(s2,n); //添加s2的前n个字符
s1.append(n,c); //添加n个字符c
puck_back
s1.puck_back(c);
查找子串
find
s1.find(str);
s1.find(str,pos); //寻找从pos开始匹配str的位置
find_first_of 第一次出现
find_last_of 最后一次出现
find_first_not_of
find_last_not_of
rfind 逆向查找
rfind(str,pos); //从pos开始,向前查找符合条件的字符串
获取子串
substr
string substr(size_t pos = 0, size_t len = npos) const;
访问变量
at
s.at(i); //i是下标
替换字符串
swap
s1.swap(s2); //交换字符串s1和s2
replace
s1.replace(pos,len,s2); //将s1中从pos下标开始的长度为n的子串用s2替换
处理 string 对象中的字符
处理每个字符?
使用基于范围的 for 语句
for(declaration:expression)
statement
使用范围 for 语句改变字符串中的字符
下标
使用下标执行迭代
使用下标执行随机访问
迭代器