一、string的初始化
首先,为了在程序中使用string类型,必须包含头文件 <string>。如下:
#include <string>
注意这里不是string.h,string.h是C字符串头文件。
string类是一个模板类,位于名字空间std中,通常为方便使用还需要增加:
using namespace std;
声明一个字符串变量很简单:
string str;
测试代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
程序执行结果为:
Hello world
world
wor
abcde
abc
AAAAA
Hello
二、string的比较等操作
你可以用 ==、>、<、>=、<=、和!=比较字符串,可以用+或者+=操作符连接两个字符串,并且可以用[]获取特定的字符。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
程序执行结果为:
Please input your name:
Zhang↙
you are not Wang!
Zhang, Welcome!
Zhang, Welcome!
上例中,“ cout<< str[i]; ”可换为: cout<< str.at(i);
三、string特性描述
可用下列函数来获得string的一些特性:
int capacity()const; //返回当前容量(即string中不必增加内存即可存放的元素个数)
int max_size()const; //返回string对象中可存放的最大字符串的长度
int size()const; //返回当前字符串的大小
int length()const; //返回当前字符串的长度
bool empty()const; //当前字符串是否为空
void resize(int len,char c); //把字符串当前大小置为len,多去少补,多出的字符c填充不足的部分
测试代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
程序执行结果为:
str is NULL.
str is abcdefg
str's size is 7
str's capacity is 15
str's max size is 4294967294
str's length is 7
str is abcdefgccc
str is abcde
四、string的查找
由于查找是使用最为频繁的功能之一,string提供了非常丰富的查找函数:(注:string::npos)
size_type find( const basic_string &str, size_type index ); //返回str在字符串中第一次出现的位置(从index开始查找),如果没找到则返回string::npos
rfind:从后往前查找子串或字符出现的位置。
size_type find( const char *str, size_type index ); // 同上
size_type find( const char *str, size_type index, size_type length ); //返回str在字符串中第一次出现的位置(从index开始查找,长度为length),如果没找到就返回string::npos
size_type find( char ch, size_type index ); // 返回字符ch在字符串中第一次出现的位置(从index开始查找),如果没找到就返回string::npos
注意:查找字符串a是否包含子串b,不是用 strA.find(strB) > 0 而是 strA.find(strB) != string:npos 这是为什么呢?(初学者比较容易犯的一个错误)本部分参考自web100与luhao1993
先看下面的代码
int idx = str.find("abc"); if (idx == string::npos);
上述代码中,idx的类型被定义为int,这是错误的,即使定义为 unsigned int 也是错的,它必须定义为 string::size_type。npos 是这样定义的: static const size_type npos = -1; 因为 string::size_type (由字符串配置器 allocator 定义) 描述的是 size,故需为无符号整数型别。因为缺省配置器以型别 size_t 作为 size_type,于是 -1 被转换为无符号整数型别,npos 也就成了该型别的最大无符号值。不过实际数值还是取决于型别 size_type 的实际定义。不幸的是这些最大值都不相同。事实上,(unsigned long)-1 和 (unsigned short)-1 不同(前提是两者型别大小不同)。因此,比较式 idx == string::npos 中,如果 idx 的值为-1,由于 idx 和字符串string::npos 型别不同,比较结果可能得到 false。因此要想判断 find()等查找函数的结果是否为npos,最好的办法是直接比较。
测试代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
运行结果:
五、其他常用函数
string &insert(int p,const string &s); //在p位置插入字符串s
string &replace(int p, int n,const char *s); //删除从p开始的n个字符,然后在p处插入串s
string &erase(int p, int n); //删除p开始的n个字符,返回修改后的字符串
string substr(int pos = 0,int n = npos) const; //返回pos开始的n个字符组成的字符串
void swap(string &s2); //交换当前字符串与s2的值
string &append(const char *s); //把字符串s连接到当前字符串结尾
void push_back(char c) //当前字符串尾部加一个字符c
const char *data()const; //返回一个非null终止的c字符数组,data():与c_str()类似,用于string转const char*其中它返回的数组是不以空字符终止,
const char *c_str()const; //返回一个以null终止的c字符串,即c_str()函数返回一个指向正规C字符串的指针, 内容与本string串相同,用于string转const char*
测试代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
程序执行结果为:
abc123defg
abcdefg
123abcdefg
123abcdefg123
123abcdefg123A
helloabcdefg123A
abcdefg
swap!
swap!
------------------------------------------
string 类还有 assign 成员函数,可以用来对 string 对象赋值。assign 成员函数返回对象自身的引用。例如:
- string s1("12345"), s2;
- s3.assign(s1); // s3 = s1
- s2.assign(s1, 1, 2); // s2 = "23",即 s1 的子串(1, 2)
- s2.assign(4, 'K'); // s2 = "KKKK"
- s2.assign("abcde", 2, 3); // s2 = "cde",即 "abcde" 的子串(2, 3)
求字符串的长度
length 成员函数返回字符串的长度。size 成员函数可以实现同样的功能。
substr 函数
string s1 = "this is ok";
string s2 = s1.substr(2, 4); // s2 = "is i"
s2 = s1.substr(2); // s2 = "is is ok"
替换子串
replace 成员函数可以对 string 对象中的子串进行替换,返回值为对象自身的引用。例如:
- string s1("Real Steel");
- s1.replace(1, 3, "123456", 2, 4); //用 "123456" 的子串(2,4) 替换 s1 的子串(1,3)
- cout << s1 << endl; //输出 R3456 Steel
- string s2("Harry Potter");
- s2.replace(2, 3, 5, '0'); //用 5 个 '0' 替换子串(2,3)
- cout << s2 << endl; //输出 HaOOOOO Potter
- int n = s2.find("OOOOO"); //查找子串 "00000" 的位置,n=2
- s2.replace(n, 5, "XXX"); //将子串(n,5)替换为"XXX"
- cout << s2 < < endl; //输出 HaXXX Potter
10. 删除子串
erase 成员函数可以删除 string 对象中的子串,返回值为对象自身的引用。例如:
- string s1("Real Steel");
- s1.erase(1, 3); //删除子串(1, 3),此后 s1 = "R Steel"
- s1.erase(5); //删除下标5及其后面的所有字符,此后 s1 = "R Ste"
11. 插入字符串
insert 成员函数可以在 string 对象中插入另一个字符串,返回值为对象自身的引用。例如:
- string s1("Limitless"), s2("00");
- s1.insert(2, "123"); //在下标 2 处插入字符串"123",s1 = "Li123mitless"
- s1.insert(3, s2); //在下标 2 处插入 s2 , s1 = "Li10023mitless"
- s1.insert(3, 5, 'X'); //在下标 3 处插入 5 个 'X',s1 = "Li1XXXXX0023mitless"
12. 将 string 对象作为流处理
使用流对象 istringstream 和 ostringstream,可以将 string 对象当作一个流进行输入输出。使用这两个类需要包含头文件 sstream。
示例程序如下:
- #include <iostream>
- #include <sstream>
- #include <string>
- using namespace std;
- int main()
- {
- string src("Avatar 123 5.2 Titanic K");
- istringstream istrStream(src); //建立src到istrStream的联系
- string s1, s2;
- int n; double d; char c;
- istrStream >> s1 >> n >> d >> s2 >> c; //把src的内容当做输入流进行读取
- ostringstream ostrStream;
- ostrStream << s1 << endl << s2 << endl << n << endl << d << endl << c <<endl;
- cout << ostrStream.str();
- return 0;
- }
程序的输出结果是:
Avatar
Titanic
123
5.2
K
第 11 行,从输入流 istrStream 进行读取,过程和从 cin 读取一样,只不过输入的来源由键盘变成了 string 对象 src。因此,"Avatar" 被读取到 s1,123 被读取到 n,5.2 被读取到 d,"Titanic" 被读取到s2,'K' 被读取到 c。
第 12 行,将变量的值输出到流 ostrStream。输出结果不会出现在屏幕上,而是被保存在 ostrStream 对象管理的某处。用 ostringstream 类的 str 成员函数能将输出到 ostringstream 对象中的内容提取出来。