您的位置:首页 > 编程语言 > C语言/C++

C++标准库类型string用法小结

2017-03-27 14:57 453 查看
标准库类型string表示可变长的字符序列,使用string类型必须首先包含string头文件。作为标准库的一部分,string定义在命名空间std中。

#include <string>
using namaspace std::string;


常用操作罗列

=, assign()   // 赋以新值
swap()   // 交换两个字符串的內容
+=, append(), push_back()  // 在尾部添加字符
insert()  // 插入字符
erase()  // 删除字符
clear()  // 删除全部字符
replace()  // 替换字符
+  // 串联字符串
==, !=, <, <=, >, >=, compare()  // 比较字符串
size(), length()  // 返回字符数量
max_size()  // 返回字符的可能最大个数
empty()  // 判断字符串是否为空
capacity()  // 返回重新分配之前的字符容量
reserve()  // 保留一定量内存以容纳一定数量的字符
[ ], at()  // 返回某一位置的字符
>>, getline()  // 输入
<<  // 输出
copy()  // 拷贝
c_str()  // 将内容以C_string返回
data()  // 返回一个非null终止的c字符数组
substr()  // 返回某个子字符串
查找函数(find, rfind...)
begin(), end()  // 提供类似STL的迭代器支持
rbegin(), rend()  // 逆向迭代器
get_allocator()  // 返回配置器


定义和初始化string对象

1.以默认的方式初始化一个string对象:

string s;  // 会得到一个空的string,该string对象中没有任何字符


2.如果提供了一个字符串字面值,则该字面值中除了最后那个空字符外其他所有的字符都被拷贝到新创建的string对象中去。

string s("Hello");  // s是字面值"Hello"的副本,除了字面值最后的那个空字符外
string s = "Hello";  // 等价于s("Hello")


3.如果提供的是一个数字和一个字符,则string对象的内容是给定字符连续重复若干次后得到的序列。

string s(10, 'a');  // 把s初始化为由连续10个字符'a'组成的串,即"aaaaaaaaaa"


string对象上的基本操作

1.读写string对象

使用IO操作符读写string对象:

// 注:在执行读取操作时,string对象会自动忽略开头的空白并从第一个真正的字符开始读起,直到遇见下一处空白
// 例如:输入“   Hello World”,输出将是“Hello”
string s;
cin >> s;
cout << s << endl;


使用getline读取一整行:

有时我们希望能在最终得到的字符串中保留输入时的空白符,这时应该用getline函数代替原来的>>运算符。getline函数的参数是一个输入流和一个string对象,函数从给定的输入流中读入内容,直到遇到换行符为止(注意:换行符也读进来了),然后把所读的内容存入到那个string对象中去(注意:不存换行符)。

string line;
while(getline(cin, line))
cout << line << endl;


2.string的empty和size操作

empty函数根据string对象是否为空返回一个对应的布尔值。

size函数返回string对象的长度(即string对象中字符的个数),size函数返回的是一个string::size_type类型的值(是一个无符号类型的值)。

3.比较string对象

相等性运算符(== 和 !=)分别检验两个string对象相等或不相等,string对象相等意味着它们的长度相同而且所包含的字符也全都相同。

关系运算符<、<=、>、>=分别检验一个string对象是否小于、小于等于、大于、大于等于另外一个string对象,这些运算符都依照(大小写敏感的)字典排序。

如果两个string对象的长度不同,且较短的string对象的每个字符都与较长string对象对应位置上的字符相同,则认为较短string对象小于较长string对象。

如果两个string对象在某些对应的位置上不一致,则string对象比较的结果是string对象中的第一对相异字符比较的结果。

标准库string类型还提供了一组compare函数进行string对象的比较:

int compare(const string &s) const;  // 比较当前字符串和s的大小
int compare(int pos, int n, const string &s) const;  // 比较当前字符串从pos开始的n个字符组成的字符串与s的大小
int compare(int pos, int n, const string &s, int pos2, int n2) const;  //比较当前字符串从pos开始的n个字符组成的字符串与s中从pos2开始的n2个字符组成的字符串的大小
int compare(const char *s) const;
int compare(int pos, int n, const char *s) const;
int compare(int pos, int n, const char *s, int pos2) const;

返回值:
>时返回1,<时返回-1,==时返回0


4.相加操作

两个string对象相加(使用加法运算符 +)得到一个新的string对象,其内容是把左侧的运算对象与右侧的运算对象串接而成。

复合赋值运算符(+=)负责把右侧string对象的内容追加到左侧string对象的后面。

string s1 = "Hello, ", s2 = "World";
string s3 = s1 + s2;  // s3的内容是"Hello, World"
s1 += s2;  // 等价于s1 = s1 + s2


字面值也可与string对象相加,但要注意,当把string对象和字符字面值及字符串字面值混在一条语句中使用时(字符串字面值与string是不同的类型),必须确保每个加法运算符(+)的两侧的运算对象至少有一个是string。

例:

string s = s1 + ",";   // 正确
string s = "hello" + ",";  // 错误
string s = s1 + "," + "world";  // 正确


处理string对象中的字符

我们经常需要单独处理string对象中的字符,有时需要处理string对象中的每一个字符,有时只需处理string对象中的某个特定的字符…

首先来了解一下改变某个字符特性的一些函数:

cctype头文件中的函数,列举几个常用的:

isalpha(c)  // 当c是字母时为真
isdigit(c)  // 当c是数字时为真
islower(c)  // 当c是小写字母时为真
isspace(c)  // 当c是空白时为真
isupper(c)  // 当c是大写字母时为真
tolower(c)  // 如果c是大写字母,输出对应的小写字母,否则原样输出c
toupper(c)  // 如果c是小写字母,输出对应的大写字母,否则原样输出c


要想访问string对象中的单个字符有两种方式:一种是使用下标,另外一种是使用迭代器。

1.使用下标

无论何时用到字符串的下标,都应该注意检查其合法性。

例:

// 使用下标运算符输出string对象中的第一个字符
if(!s.empty())
cout << s[0] << endl;

// 使用下标执行随机访问--把0到15之间的十进制数转换成对应的十六进制数
const string hexdigits = "0123456789ABCDEF";
string result;
string::size_type n;
while(cin >> n)
if(n < hexdigits.size())
result += hexdigits
;
cout << "Your hex number is: " << result << endl;


2.使用迭代器

迭代器提供对对象的间接访问,其对象是容器中的元素或者string对象中的字符。使用迭代器可以访问某个元素,也可以从一个元素移动到另一个元素。

例:

// 处理string对象中的字符直至处理完全部字符或遇到空白
string::iterator it;
for(it = s.begin(); it != s.end() && !isspace(*it); ++it)
*it = toupper(*it);  // 将当前字符改成大写形式


构造string的其他方法

1.string s(cp, n)

s是cp指向的字符数组中的前n个字符的拷贝。此数组至少应该包含n个字符。

例:

const char *cp = "Hello World!";
char noNull[] = {'H', 'i'};
string s1(cp);  // 拷贝cp中的字符直到遇到空字符 '\0',s1 == "Hello World!"
string s2(noNull, 2);  // 从noNull拷贝两个字符,s2 == "Hi"
string s3(noNull);  // 未定义:noNull不是以空字符 '\0' 结束


2.string s(s2, pos2)

s是string s2从下标pos2开始的字符的拷贝。若pos2 > s2.size(),构造函数的行为未定义。

例:

const char *cp = "Hello World!";
string s1(cp);  // 拷贝cp中的字符直到遇到空字符 '\0',s1 == "Hello World!"
string s2(s1, 6);  // 从s1[6]开始拷贝,直至s1末尾,s2 == "World!"
string s3(s1, 16);  // 抛出out_of_range异常


3.string s(s2, pos2, len2)

s是string s2从下标pos2开始len2个字符的拷贝。若pos2 > s2.size(),构造函数的行为未定义。不管len2的值是多少,构造函数至多拷贝s2.size() - pos2个字符。

例:

const char *cp = "Hello World!";
string s1(cp);  // 拷贝cp中的字符直到遇到空字符 '\0',s1 == "Hello World!"
string s2(s1, 6, 5);  // 从s1[6]开始拷贝5个字符,s2 == "World"
string s3(s1, 6, 15);  // 从s1[6]开始拷贝,只拷贝到s1末尾,s3 == "World!"


4.substr操作

s.substr(pos, n) 返回一个string,包含s中从pos开始的n个字符的拷贝。pos的默认值为0。n的默认值为s.size() - pos,即拷贝从pos开始的所有字符。

例:

string s("Hello world");
string s2 = s.substr(0, 5);  // s2 == "Hello"
string s3 = s.substr(6);  // s3 == "world"
string s4 = s.substr(6, 11);  // s4 == "world"
string s5 = s.substr(12);  // out_of_range


修改string的操作

1.assign操作

string &assign(const char *s);  // 用c类型字符串s赋值
string &assign(const char *s, int n);  // 用c字符串s开始的n个字符赋值
string &assign(const string &s);  // 把字符串s赋给当前字符串
string &assign(int n, char c);  // 用n个字符c赋值给当前字符串
string &assign(const string &s, int start, int n);  // 把字符串s中从start开始最多n个字符赋给当前字符串
template <class InputIterator>
string& assign (InputIterator first, InputIterator last);  // 把first和last迭代器之间的部分赋给字符串


2.insert操作

// 以下4个函数在p位置之前插入字符串s中pos开始最多n个字符
string &insert(int p, const char *s);
string &insert(int p, const char *s, int n);
string &insert(int p, const string &s);
string &insert(int p, const string &s, int pos, int n);

string &insert(int pos, int n, char c);  // 在pos之前插入n个字符c
iterator insert(iterator it, char c);  // 在it之前插入字符c,返回插入后迭代器的位置
template <class InputIterator>
void insert (iterator p, InputIterator first, InputIterator last);  // 在it之前插入[first,last)之间的字符
void insert(iterator it, int n, char c);  // 在it之前插入n个字符c


3.erase操作

iterator erase(iterator first, iterator last);  // 删除[first,last)之间的所有字符,返回指向最后一个被删元素之后元素的迭代器
iterator erase(iterator it);  // 删除it指向的字符,返回被删元素之后元素的迭代器
string &erase(int pos = 0, int n = npos);  // 删除pos开始的n个字符,返回修改后的字符串


4.append操作

append操作是在string末尾进行插入操作的一种简写形式:

例:

string s("Hello"), s2 = s;  // 将s和s2初始化为"Hello"
s.insert(s.size(), " world");  // s == "Hello world"
s2.append(" world");  // 等价方法,s == s2


5.replace操作

replace操作是调用erase和insert的一种简写形式:

例:

string s("C++ 4th Edition"), s2 = s;  // 将s和s2初始化为"C++ 4th Edition"
s.erase(4, 3);  // s == "C++  Edition"
s.insert(4, "5th");  // s == "C++ 5th Edition"
s2.replace(4, 3, "5th");  // 等价方法:s == s2


string搜索操作

函数原型如下(rfind()类似,只是从反向查找):

size_t find (const string& str, size_t pos = 0) const;  // 从pos开始查找字符串s在当前串中的位置
size_t find (const char* s, size_t pos = 0) const; // 从pos开始查找字符串s在当前串中的位置
size_t find (const char* s, size_t pos, size_t n) const;  // 从pos开始查找字符串s中前n个字符在当前串中的位置
size_t find (char c, size_t pos = 0) const;  // 从pos开始查找字符c在当前字符串的位置

返回值:
找到则返回第一个字符的索引
没找到则返回 string::npos


例:

string name("AnnaBelle");
int pos = name.find("Anna");  // pos == 0
pos = name.find("anna");  // pos == npos


其他还有 find_first_of(),find_last_of(),find_first_not_of(),find_last_not_of(),作用是查找字符串中任一个字符满足的查找条件。

例:

string s("cobra");
int index = s.find_first_of("hark");  // 返回3,因为"hark"中的字符在s--"cobra"中第一次出现的是字符'r'(3为"cobra"中'r'的索引)
index = s.find_last_of("hark");  // 返回4,因为"hark"中的字符在s--"cobra"中最后一次出现的是字符'a'(4为"cobra"中'a'的索引)


string和C字符串的转换

C++提供的由C++字符串得到对应的C_string的方法是使用data()、c_str()和copy(),其中,data()以字符数组的形式返回字符串内容,但并不添加’\0’。c_str()返回一个以’\0’结尾的字符数组,而copy()则把字符串的内容复制或写入既有的c_string 或字符数组内。C++字符串并不以’\0’结尾。

const char *data() const;  // 返回一个非null终止的c字符数组
const char *c_str() const;  // 返回一个以null终止的c字符串
int copy(char *s, int n, int pos = 0) const;  // 把当前串中从pos开始的n个字符拷贝到以s为起始位置的字符数组中,返回实际拷贝的数目


参考资料:

C++ string 用法詳解. https://www.byvoid.com/zht/blog/cpp-string

标准C++中的string类的用法总结. http://www.cnblogs.com/xFreedom/archive/2011/05/16/2048037.html

《C++ Primer(第5版)》

更多C++标准库类型string的资料可查阅 http://www.cplusplus.com/reference/string/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: