C++STL字符串string知识汇总,恶补!

基础不牢,地动山摇。
今天小米的笔试编程题,输入格式是一整个字符串,需要从字符串中分割出数据,同时还需要将字符串转换为int数值。
本来用C++写,写到一般想起来了C++中没有split()函数,想到在java中有这个函数,于是又换到了Java语言,但是Java的输入、输出又不方便,唉~~
这波,让我狠狠地补一下string的知识

今天来将C++ STL中,与字符串相关的东西总结一下。

string

在C++中,用string类变量来表示一个字符串,相比于C中的char[],更简单。

创建string字符串对象

创建一个string对象

string s; // 1. 一个空的字符串对象

string s1 = "lmk"; // 2. 创建指定内容的字符串

char st[] = {'1','a','b'};
string s2(st);// 3. 根据char[] 创建字符串

string s3(10, 'c'); // 4. 生成包含n个指定字符的字符串

常规用法

string字符串本质还是一个char[],所以我们可以利用[]来访问指定位置的字符

string str = "abc";
cout << str[0] << endl;
cout << str[2] << endl;

string重载了++=运算法,这两个运算符对于string对象,就是字符串拼接操作

string str = "abc";
cout << str + "1234" << endl;

str += "xyz";
cout << str << endl;

str += 'Y';
cout << str << endl;

string中常用的成员方法

迭代器:
  1. begin()用来标识字符串的起始位置,即第一个字符的位置
  2. end(),用来表示字符串的结束位置,即最后一个字符的下一个位置
基本成员方法

首先是基本的成员方法

  1. 获取字符串长度size()length()
  2. 判断字符串是否为空empty()
  3. 清空字符串clear()
string str = "lmkdsb";
cout << str.size() << " || " << str.length() << endl;
str.clear();
cout << str.size() << " || " << str.length() << endl;
cout << str.empty() << endl;
添加

字符串长度增加相关的方法

  1. 尾插单个字符push_back(char ch)
  2. 追加字符串,append(string str),此方法的参数是一个字符串,追加字符串后面
  3. 插入字符或字符串`insert(int pos, string)
string str = "lmkdsb";

str.push_back('x'); // 追加单个字符
cout << str << endl;

str.append("123"); // 追加字符串
cout << str << endl;

str.insert(1, "xyz"); // 在指定索引处插入字符串
cout << str << endl;

str.insert(str.end(), 'Y'); // 如果要使用insert()在指定索引处插入一个字符,必须要使用迭代器来指明位置
cout << str << endl;
删除

删除字符串相关的方法

  1. 删除最后的那个字符,尾删pop_back()
  2. 删除指定位置的一个或一些字符earse()
string str = "lmkdsbxxxw";

str.pop_back(); // 删除末尾的单个字符
cout << str << endl;

str.erase(6);// 从pos索引开始删除,一直到最后
cout << str << endl;

str.erase(2, 3); // 从索引为2的位置开始,删除3个元素
cout << str << endl;

str.erase(str.begin() + 1, str.end() - 1); // 配合迭代器,删除[start, end)之间的元素
cout << str << endl;
查找

字符串查找:

  1. find()从左侧开始查找,返回起始位置的坐标
  2. rfind()从右侧开始查找,返回起始位置的坐标
    这两个方法如果找不到,那么就会返回string::npos,(no position),此成员变量用来表示没有找到目标字符串。
    此成员是一个long long unsigned int类型的变量(64位无符号整型),npos转换为int是会溢出,最终转换为int是-1
string str = "lmkdsbm";

cout << str.find('m') << endl;  // 查找单个字符
cout << str.find("mk") << endl; // 查找子字符串
cout << str.find('m',1) << endl; //从指定位置开始查找,从[pos, ]开始查找

// 从右边开始查找
cout << str.rfind('m') << endl;
cout << str.rfind("mk") << endl;
cout << str.rfind('m', 3) << endl; // 从指定位置开始查找

// 找不到会返回npos
cout << str.find('x') << endl; // 结果是 18446744073709551615
int pos = str.find('x'); // 转换为int会溢出,最终结果是-1
cout << pos << endl;

此外,还有两个查找相关的方法,与find()、rfind()相似:

  1. find_first_of查找第一个出现的位置
  2. find_last_of查找最后出现的位置
string str = "lmkdsbmx";
// 查找第一个出现的位置
cout << str.find_first_of('m') << endl;
cout << str.find_first_of('m', 1) << endl; // 从指定位置开始查找

// 查找第一个不包含指定子串的位置
cout << str.find_first_not_of('m', 1) << endl;

cout << str.find_last_of('m') << endl; // 寻找最后出现的位置
cout << str.find_last_not_of('m') << endl; // 寻找最后不出现目标字符串的位置

两个字符串交换内容,swap(string str)

string str = "abc";
string tmp ="1231";
str.swap(tmp); // swap()的参数必须是一个变量,不能是一个字符串常量,str.swap("123")这种写法是不可以的
cout << str << endl;
cout << tmp << endl;
替换

replace(pos, n, string&)从pos位置开始长度为n的这段区间替换为str。
replace(pos,n, m, char ch)从pos位置开始长度为n的这段区间替换为m个ch

string str = "abcdef";

str.replace(2,2, "lmk"); 
cout << str << endl;

string s = "xyzw";
s.replace(1,2,8,'k');
cout << s << endl;

字符串分割

substr(pos, n)从字符串中分割出子串,从pos位置开始,截取n个字符并返回

string str = "abc123";
cout << str.substr(2) << endl; // 从指定位置开始截取,一直到结尾
cout << str.substr(3,3) << endl; // 从指定位置pos开始截取n个字符

在C++中,并没有split()函数,其他语言中都有这个函数,这个函数的作用就是按照指定的字符串作为分割,返回分割后的结果。
例如,string str = "13,2,3",按照split()所说的,我们按照逗号,进行分割,分割后的结果应该是一个数组,["13,"2","3]"
我们可以手动实现这个函数,实现的思路有很多种,我们这里以find()substr()来实现

vector<string> split(string str, string separator){
    vector<string> res;
    int pos = str.find(separator);
    while(pos != -1){
        string part = str.substr(0, pos);
        res.push_back(part);
        str = str.substr(pos + 1);
        pos = str.find(separator);
    }
    if(!str.empty()){
        res.push_back(str);
    }
    return res;
}

关于更多split()方法的实现方式可以看Site Unreachable

其他操作

字符转换大小写

  • tolower(char ch) 将一个字符转换为小写并返回
  • toupper(char ch)将一个字符转换为大写并返回
char ch = 'a';
ch = toupper(ch); // 转换为大写
cout << ch << endl;

ch = tolower('Q'); // 转换为小写
cout << ch << endl;

ch = tolower('2'); // 如果不能转换,则原样返回
cout << ch << endl;

字符判断

判断一个字符是不是字母、是不是大/小写字母、是不是数字

cout << isupper('A') << endl;   // 是否是大写字母
cout << isupper('a') << endl;

cout << islower('A') << endl;   // 是否为小写字母


cout << isdigit('1') << endl;   // 是否是数字
cout << isdigit('x') << endl;

cout << isalpha(',') << endl; // 是否为字母
cout << isalpha('X') << endl; 

string字符串与其他基本数据类型的转换

对于string字符串风格的对象来说,将一个string转换为int,可以使用stoi(string& str)函数,除此之外还有:

  • stoi(), string对象转换为int
  • stof(),string对象转换为float
  • stod(),string对象转换为double
  • stoll(),string对象转换为long long
string str = "123";
int num = stoi(str); // string 转换为int
cout << num + 5 << endl;

str = "123.456"; // 转换为float
cout << stof(str) + 0.1 << endl;

cout << stod(str) << endl; // 转换为double

str = "123212354312523292";
long long x = stoll(str);
cout << x << endl; // 转换为long long 类型

你可能还听说过C 函数库中有一个atoi()将字符串转换为int,这个atoi(char* s)函数的参数是一个C风格的字符串,即一个char的数组,不能传递string对象作为参数。

其他数据类型转换为string

可以调用to_string()函数,该方法是C++11中新增的,该函数可以将其他所有的基本数据类型转换为字符串

string s = to_string(123);
s.pop_back();
cout << s << endl;

string st = to_string(123.456);
cout << st << endl;

字符串反转

可以直接调用STL中的reverse()函数,
该函数需要两个参数:

  • 第一个参数,容器的起始位置
  • 第二个参数,容器的结束位置
string str = "abcdef";
reverse(str.begin(), str.end());
cout << str << endl;

sort()与string

我们知道STL中,sort()是对容器内元素进行排序的,同样也支持对string对象中字符的排序,因为我们可以把string对象看做盛放字符的容器。
众所周知,sort()函数至少需要两个参数:

  • 第一个是容器的开始位置,
  • 第二个是结束位置,
  • 第三个参数是可选的,自定义排序规则。
string str = "cbadfe";
sort(str.begin(), str.end());
cout << str << endl; // 结果是 abcdef

对于sort()函数来说,如果不传入自定义的比较规则,则会按照从小到大的顺序排序,对于字符来说,会按照字典序排序。

transform()

transform()函数的作用就是将一个容器中的所有元素做出转换。
比如,我的字符串是"abc"可以利用transform()将字符串中的元素全部转换为大写"ABC"
transform()有多个重载形式,对于string来说,就这种形式比比较常用

transform(begin, end, res, operation)
  • begin容器的起始位置
  • end容器的结束位置
  • res,用来接受转换完成后的结果,从哪个变量的哪个位置开始接收转换后的结果
  • operation,具体的转换逻辑,我们可以使用STL内置的函数,也可以自定义
    以转换大写字母为例,
string str = "abcdefg";
transform(str.begin(), str.end(), str.begin(), ::toupper);// ::这两个冒号不可以省略
cout << str;

当然自定义逻辑也是很简单的

// 是大写就转换为小写,是小写就转换为大写
char myChange(char ch){
    if(isupper(ch)){
        return tolower(ch);
    }else{
        return toupper(ch);
    }
}
int main()
{
    string str = "aBcDeFg";
    transform(str.begin(), str.end(), str.begin(), myChange);// ::这两个冒号不可以省略
    cout << str;
    return 0;
}

参考文章

posted @ 2023-09-03 00:47  秋天Code  阅读(11)  评论(0编辑  收藏  举报  来源