本文主要介绍c++标准库中 string 的基本用法。
string表示可变长字符序列,其定义在命名空间std中,使用时记得包含头文件:
1
2
3
4
5
6
7
8
9
10
11
|
os<<s ////将s写入到输出流os中,返回os
is>>s ////从is中读取字符串到s中,字符串用空白(空格符,换行,制表符)隔开,返回is
getline(is,s) ////从is中读取一行赋给s,返回is
s.empty() ////判断s是否为空
s.size() ////返回s的字符个数
s[n] ////返回s中第n+1个字符的引用,使用时需要判断s是否为空!
s1+s2 ////连接
s1=s2 ////用s2的副本代替掉s1
s1==s2 ////等性判断,对大小写敏感
s1!=s2 ////等性判断,对大小写敏感
<,<=,>,>= ////比较字符串大小关系,对大小写敏感
|
输入输出流最常用的还是标准库中的iostream,这里想说cin>>s和 getline(cin,s) 的区别:
- cin>>s 会忽略掉输入开头的空白,从第一个真正字符开始读起,直到遇见下一个空白为止(该空白没被读入)。
- getline(cin,s)从给定输入流开始读取,直至遇到换行符结束,注意换行符也被读入,然后将读取的所有内容(除了最后的换行符外)放到s中。(s不包含换行符)。
s.size() 是一个string::size_type类型,把它简单理解为一个无符号整形就好,但特殊的是该类型能够存放任何 string 对象的大小(理解为一个很大的值,手动狗头...)
c++11标准中允许用auto和decltype推断一个变量的类型。使用auto必须初始化变量,比如:
1
2
|
auto s; ////错误,s没初始化,这让编译器怎么推断...
auto s = "hello"; ////正确,编译器推断"hello"的类型,并认为也是s的类型。
|
decltype可用于不初始化一个变量这种情况,这样用:
其实是编译器从 s.size() 中推断出一个类型,并认为s1也是该类型。
c++11提供的范围for语句很好用,如下:
1
2
3
4
5
6
7
|
string s("hello world!");
for(auto &c : s)
{
c = toupper(c);
}
cout<< s <<endl;
|
这里值得注意的是:若要改变string对象中字符的值,必须把循环变量定义成引用类型。
可使用下标或者使用迭代器访问单个字符。
- 使用下标:下面的例子是将输入的一行字符串中第二个单词全部大写,最后输出。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
#include "stdafx.h"
#include <iostream>
#include<string>
using namespace std;
////利用下标运算符处理特定位置的部分字符串
int main()
{
string line1;
getline(cin, line1); /////获取输入第一行
if (!line1.empty() && !isspace(line1[0]))
{
int word_count = 0;
for (decltype(line1.size())index = 0; index != line1.size(); index++)
{
if (isspace(line1[index]))
word_count++;
if (word_count == 1) ////处理第二个单词
{
line1[index] = toupper(line1[index]); ////将第二个单词大写
}
}
cout << line1 << endl;
}
else
cout << "input error" << endl;
return 0;
}
|
若要用下标的方式访问字符,一定要先检查字符串是否为空,否则容易出现不可预知的结果。
- 使用迭代器
1
2
3
4
5
6
|
string str{ "some string" };
for(auto s = str.begin(); s != str.end(); ++s)
{
*s = toupper(*s);
}
cout << str << endl;
|