标准库类型string笔记
永远不要忘了包含文件和使用命名空间
#include <string>
using namespace std;
string对象上的操作
读写string对象
string s
cin>>s
使用cin
读string对象时,会:
- 忽略开头的空白字符(空格符、换行符、制表符等)
- 到下一个空白字符结束
读写未知数量的string对象
int main()
{
while(cin>>s)
cout<<s<<endl;
return 0;
}
上面的程序除非用户输入Ctrl+Z (Windows的文件结束符EOF)才会结束while循环,否则用户可以一直输入,回车后程序每行输出一个单词。
getline读一整行
将上述代码的循环条件换为while(getline(cin,s))
可以实现用户输入一行,程序读一行。除了最后的换行符,其他空白符号都会保留。此外getline有一种重载形式可以实现根据间隔符将字符串切片,配合fstream和sstream,可以将csv等文件数据读取到vector容器中。
string的empty和size操作
string::empty()函数判断string对象是否为空返回布尔值,为空则返回True
。如果使用了cin来输入,则除非用户Enter前没有任何输入,否则(如之前有空格符、制表符等空白符号)都不为空。
string::size()求取string对象的长度,返回值是size_t
类型(string::size_type,一种无符号整形数)。
> #include <typeinfo>
string s;
...
cout<<typeid(s.size()).name()<<endl;得到unsigned int的结果1
C++11新标准中可以使用
auto
或者decltype
类型来让编译器自动推断变量类型,避免int 和size_t混用带来的问题:
auto len = line.size();
string初始化
常规的初始化不再赘述,这里提若干种特殊的初始化。
-
string s(4,'a')
,此时s = “aaaa”。要注意的是第二个参数只能是单个字符的char类型。 -
string s2(s1, 0, 3)
从已有的string对象中第0个位置(含)开始截取3个字符组成字符串作为s2。另一种方式是string s2 = s1.substr(0,3)
也可以达到相同的效果
字面值和string对象相加
因为某些历史问题,字面值和string是不同的类型,这要求加法运算符必须有一个运算对象是string,不能两个都是字面值。比如下面的例子就是错误的:
string s = "123" + "asd";
处理string中的字符
C++11中的范围for
和Python的for有些像,C++11新标准提供了一种范围for来遍历序列中的元素并进行操作:
for (declaration : expression)
statement
将string s
中每个字符的变为大写就可以写成:
for (auto &c : s) //如果对字符进行更改需要使用引用
c = toupper(c)
也可以使用下标[]对string中的字符进行操作。
书中2有一段将用户输入的数字转化为16进制的代码样例:
const string h = "0123456789ABCDEF";
string result;
size_t n;
while(cin>>n)
if(n < h.size())
result += h[n];
cout<<result<<endl;需要注意的是,这个例子的cout在while循环之后,因此除非用户输入Ctrl+Z,或者输入了非法字符(非size_t类型,也就是非数字)后Enter,否则程序不会执行输出语句
除了s[n]之外,s.at(n)也可以达到相同的效果。但当出现数组越界时,后者可以抛出一个异常(如下所示),这样就提供了友好的提示和解决渠道3。
try
{
s.at(5);
}
catch(exeption& e)
{
cerr<<e.what()<<endl;
}
其他操作
增加的方法除了+符号之外,增加append()的参数构成和字符串的多种初始化方法类似,这里不再赘述;
s1.replace(1,2,"abc")
最简单的3参数形式:把s1[1]开始2个字符换成”abc”;s1.swap(s2)
,交换两个字符串;find('a', 2)
第一个参数是要查找的char或string,第二个参数是开始查找的下标(缺省0)。找不到则返回值为string::npos
合理使用各种字符串的操作方法,可以实现一些很实用的小功能:
trim函数
string没有像CString等那样的去除首尾空白字符的trim()函数,以下代码实现了这个函数4
string trim(string &s)
{
if(s.size() == 0) //s为空串
return s;
size_t beg = s.find_first_not_of(" \a\b\f\n\r\t\v");
size_t end = s.find_last_not_of(" \a\b\f\n\r\t\v");
if(beg == string::npos) //s中全是空白字符
return "";
return string(s, beg, end-beg+1);
}
- http://bbs.csdn.net/topics/100118992 #3 ↩
- C++Primer中文版(第5版),电子工业出版社,75~86 ↩
- C++编程思想,机械工业出版社,523 ↩
- C++编程思想,机械工业出版社,517 ↩