在STL(Standard Template Library)中,提供了string类操作字符串,最近学习了该类的一些方法,现在分享一些学习心得。
在c++中,字符串被当作以’\0’结束的char数组。string类将字符串看成一个对象,类中提供了很多方法便于我们操作字符串。首先看看构造方法:
- string str : 构造一个空字符串
- string str(“ysg”):字符串常量构造
- string str(string s):字符串对象构造新字符串
- string str(string s,first,last):利用字符串s的[first,last]构造新字符串
- string str(char c[]):用char数组构造字符串
- string str(char c[],first,last):用char数组的[first,last]区间构造新字符串,与利用string构造一样
- string str(int number,char c):构造number个c的字符串
可以看到,在构造string对象时,我们不能用数值或字符直接构造。大多数是用字符串常量、字符数组和字符串构造新的字符串对象。
字符串遍历
在STL库中的大多数容器,都可以生成对应的迭代器,迭代器类似指针,可以很方便地操作容器中的数据。string类也可以生成迭代器,主要通过字符串对象的begin()、end()、rbegin()和rend()方法生成。
迭代器可以分为正向迭代器和反向迭代器。begn()和end()返回的是正向迭代器,调用begin()方法返回的迭代器指向第一个元素,调用end()方法返回的迭代器指向最后一个元素的后一个位置。rbegn()和rend()返回的是反向迭代器,调用rbegin()方法返回的迭代器指向最后一个元素,调用rend()方法返回的迭代器指向第一个元素的前一个位置。
下面简单示例一下迭代器的用法。
#include<iostream>
#include<string> //使用string类
using namespace std;
int main()
{
string str("ysgncss");
string::iterator it1; //正向迭代器
for (it1 = str.begin(); it1 != str.end(); it1++)
{
cout << *it1;
}
cout << endl;
string::reverse_iterator it2; //反向迭代器
for (it2 = str.rbegin(); it2 != str.rend(); it2++)
{
cout << *it2;
}
return 0;
}
字符串元素访问
c++的string作为一个对象,但类中重载了操作符[]。所以字符串作为字符串支持两种方式访问其中的元素。
- 随机访问:数组的下标访问方式,如str[0]。
- 类成员函数at():利用string对象的at()函数访问,如str.at(0)。
当然,利用上面遍历字符串的迭代器,我们也可以利用迭代器来访问元素。
字符处理函数
在c++系统中,提供了很多处理字符串中字符的相关函数,常见的如下:
- isalnum(char c):判断c是否为字母或数字
- isdigit(c):判断c是否为数字
- isalpha(c) :判断c是否为字母
- islower(c):判断c是否为小写字母
- isupper(c):判断c是否为大写字母
- isspace(c):判断c是否为空白字符
- tolower(c):转换为小写字母
toupper(c):转换为大写字母
下面用了上面的一些方法来实现,给定一个字符串将其中大写字母转化为小写字母,反之亦然。
#include<iostream>
#include<string> //使用string类
using namespace std;
int main()
{
string str;
cin >> str;
string::iterator it1 = str.begin();
string::iterator it2 = str.end();
for (it1; it1 != it2; it1++)
{
if (islower(*it1))
{
*it1=toupper(*it1);
}
else
{
*it1=tolower(*it1);
}
}
cout << str << endl;
return 0;
}
修改字符串内容
在Java中,字符串创建后是不可修改的,但c++中可以利用string对象的方法来修改字符串。
1.赋值操作(字符串类重载了=)
- assign(string str):用str字符串重新给对象赋值
- assign(string str,int index,int number):用str字符串从下标index开始,取number个字符赋值
- assign(int number,char c):用number字符c赋值
- assign(string::iterator first,string::iterator last):用迭代器区间的字符赋值
- =(string str):用等号直接赋值
string str("123456ysg");
string s2;
s2.assign(str); //利用str赋值
cout << s2 << endl;
s2.assign(str, 5, 3); //从str[5]开始取3个字符赋值
cout << s2 << endl;
s2.assign(4, 'a'); //利用4个a赋值
cout << s2 << endl;
s2.assign(str.begin(), str.end() - 1); //利用迭代器赋值
//输出123456ys,因为end()的迭代器指向最后一个元素的后一个位置
cout << s2 << endl;
2.字符串后追加内容(字符串类重载了+=)
- append(string str):在字符串尾追加s
- append(string str,int index,int number):在字符串尾追加,从str字符串下标index开始,number个字符
- append(1,char c):在字符串尾追加单个字符
- push_back(char c):在字符串尾追加单个字符
- +=(string s):在原字符串尾追加s
用重载符+=追加的时候要求+=后面必须是一个string对象或字符串常量,不能是一个字符。
3.插入、删除和替换操作
- insert(int index,string s):从原string对象的index从插入一个字符串
- erase(int index):删除string[index]及后面的字符
- erase(int index,int number):删除string[index]开始的number个字符
- replace(int index,int number,string s):从源string的index开始的number个字符,替换为s
- replace(int index,int number,int n,char c):从源string的index开始的number个字符,替换为n个字符c
- swap(string s):与另一字符串交换内容
当我们对中文进行插入或者删除等操作时,由于中文占2个字符,可能会引起乱码问题。
string s = "你好";
//s.insert(1, "hello");
s.erase(1, 1);
cout << s << endl;
4.查找
利用string类的查找函数,可以快速确定找出字符串中是否存在指定字符或字符串。STL提供了以下几种方法:
- find(string s,int index=0):从字符串下标index开始,查找字符串s第一次出现的位置,若存在,返回该位置;否则,返回-1
下面我用replace和find方法简单实现了:给定一串字符串,替换其中字符串“C++”为“***”。
#include<iostream>
#include<string> //使用string类
using namespace std;
int main()
{
const string str = "C++";
const string replaceStr = "***";
string s = "hello everyone,I am ysg.I like C++ because C++ is interesting.";
int index = 0; //查找下标
int length = str.length();
while (true)
{
//每次从上一次的index + length位置开始查找
index = s.find(str, index+length);
if (index == string::npos)
{
break;
}
//s的index 开始的legnth个字符 替换成replaceStr字符串
//s.replace(index, length, replaceStr);
//s的index 开始的legnth个字符 替换成length个 字符'*'
s.replace(index, length, length, '*');
}
cout << s << endl;
return 0;
}
- find_first_of():查找指定字符或字符串第一次出现的位置
- find_last_of():查找指定字符或字符串最后一次出现的位置
- find_first_not_of():查找非指定字符或字符串第一次出现的位置
- find_last_not_of():查找非指定字符或字符串最后一次出现的位置
- substr(int index,int number):返回原字符串从下标index开始,number个字符的子串
利用find_first_not_of()和find_last_not_of()方法,我们可以简单实现去掉一个字符串的两端空格。如“ hello world. ”,变为“hello world”。
#include<iostream>
#include<string> //使用string类
using namespace std;
int main()
{
string str = " hello world. ";
string s = " ";
string result;
int first = str.find_first_not_of(s);
int last = str.find_last_not_of(s);
//取str的first到last 的子串
result = str.substr(first, last - first + 1);
cout << result << endl;
cout << result.size() << endl;
}
字符串与其他数据类型的转化
- 字符串转整型
int n = 100;
string result;
stringstream ss; //包含sstream头文件
ss << n;
ss >> result;
- 整数转字符串
string str="100";
int result;
stringstream ss;
ss << str;
ss >> result;
cout << result;