济南网站建站推广,做网站大记事代码,软件开发项目经验,系统开发过程中的第一个文档引言
针对C中的string#xff0c;本文主要讲解如何对其进行插入、删除、查找、比较、截断、分割以及与数字之间的相互转换等。
字符串插入
1. append方法
std::string str hello;
str.append(7, w); // 在末尾添加7个字符w
str.append(wwwwwww);…引言
针对C中的string本文主要讲解如何对其进行插入、删除、查找、比较、截断、分割以及与数字之间的相互转换等。
字符串插入
1. append方法
std::string str hello;
str.append(7, w); // 在末尾添加7个字符w
str.append(wwwwwww); // 在末尾添加一个字符串两个参数第一个是字符个数第二个是目标字符一个参数要拼接的字符串返回值是对象的引用也就是可以有如下用法
std::string str;
str.append(1, c).append(abc).append(d); // strcabcd2. 通过加法来拼接
std::string str hello;
str world; // 第一种加法
// str str world; // 第二种加法简单比较下两种加法的开销
#include string
#include iostream
#include chrono
void costTime(void(*f)(), const std::string info)
{auto beforeTime std::chrono::steady_clock::now();f();auto afterTime std::chrono::steady_clock::now();double duration_millsecond std::chrono::durationdouble, std::milli(afterTime - beforeTime).count();std::cout info total cost duration_millsecond ms std::endl;
}int main () {costTime([](){std::string str;for (int i 0; i 10000; i) {str wwwwwww;} }, );costTime([](){std::string str;for (int i 0; i 10000; i) {str str wwwwwww;} }, );return 0;
}执行结果 total cost 0.167382mstotal cost 128.886ms由此可见的方式效率要高出许多所以在需要考虑这类性能的时候尽量能使用就尽量使用。至于其中的原因简单理解为的方式每次赋值前都需要创建一个和str几乎等同的空间上临时对象也就是str的空间越大随之而来的创建临时对象所需的时间就会越长最终导致效率极低。
3. push_back方法 这个方法就比较简单了就是在尾部追加一个字符就不做介绍了。
4. insert方法
std::string str abc;
// 在指定位置插入字符串
str.insert(2, ef);
assert(abefc str);// 在指定位置插入多个字符
str.insert(0, 3, x);
assert(xxxabefc str);// 在指定位置迭代器插入字符或多个字符
str.insert(str.begin() 1, y);
str.insert(str.begin(), 2, t);
assert(ttxyxxabefc str);// 在指定位置插入字符串的指定子串
// 插入的是从1的位置开始的3个字符
str.insert(0, hgjkr, 1, 3);
assert(gjkttxyxxabefc str);字符串删除
std::string str abcdefght;
// 从指定位置开始删除指定长度的字符
str.erase(2, 2);
assert(abefght str);// 从指定位置删除至末尾
str.erase(4);
assert(abef str);// 从指定位置迭代器删除至末尾
str.erase(str.begin() 2);
assert(ab str);// 从指定开始位置迭代器删除至指定结束位置迭代器
// 左闭右开
str.erase(str.begin() 1, str.end());
assert(a str);字符串查找
1. find方法
std::string str abc bdef;
// 从左向右查找目标字符第一次出现的位置下标
int pos str.find(b);
assert(pos 1);
// 从左向右查找目标字符串第一次出现的位置下标
pos str.find(bd);
assert(pos 4);// 从指定位置开始查找目标字符或字符串
pos str.find(b, 2);
assert(pos 4);如果目标字符或字符串不存在则返回std::string::n_pos; 简单测试下按字符查找和按字符串查找的效率
int main() {costTime([](){std::string str abcdefgtbxyx;for (int i 0; i 100000; i) {str.find(x);} }, str);costTime([](){std::string str abcdefgtbxyx;for (int i 0; i 100000; i) {str.find(x);} }, char);
}耗时如下可以看出同样查找x的位置按字符的方式查找要比按字符串的方式查找更快。
str total cost 3.22321ms
char total cost 0.250851ms2. rfind方法 参数同find区别在于它的查找方向是从右向左。
std::string str abc bdef;
int pos str.rfind(b);
assert(pos 4);3. find_first_of/find_first_not_of
std::string str abcfbcg;
// 从左向右查找第一次出现在目标字符串中的字符
// 字符c存在于目标字符串fcg所以返回pos2
int pos str.find_first_of(fcg);
assert(pos 2);对于pos find_first_of(fcg)可以简单理解为
unsigned int pos1 str.find(f);
unsigned int pos2 str.find(c);
unsigned int pos3 str.find(g);
unsigned int pos std::min(pos1, pos2, pos3);而find_first_not_of则正好相反查找第一次不包含目标字符的位置。
std::string str abcdef;
int pos str.find_first_not_of(abc);
assert(pos 3);4. find_last_of/find_last_not_of 使用方式同find_first_of/find_first_not_of只不过查找方向是从右向左
std::string str abccfg;
int pos str.find_last_of(cab);
assert(pos 3);pos str.find_last_not_of(cgf);
assert(pos 1);字符串替换
字符串替换使用replace接口
std::string str hello world;
// 指定位置指定长度的子串替换为目标字符串
// 从5的位置长度为1的子串空格替换为::
str.replace(5, 1, ::);
assert(hello::world str);// 指定位置指定长度的子串替换为指定数目的目标字符
// 从5的位置长度为2的子串::替换为2个字符!
str.replace(5, 2, 2, !);
assert(hello!!world str);// 指定位置指定长度的子串替换为目标字符串中指定位置的子串
// 从5的位置长度为2的子串!!替换为目标串3的位置长度为2的子串..
str.replace(5, 2, hjk..kl, 3, 2);
assert(hello..world str);// 替换为目标串0的位置开始长度为2子串??
// 此重载方法对于参数为const char*类型结果如下
str.replace(5, 2, ??##, 2);
assert(hello??world str);// 替换为目标串中2的位置开始到末尾的子串##
// 此重载方法对于参数为string类型的结果如下
std::string str2 ??##;
str.replace(5, 2, str2, 2);
assert(hello##world str);// 迭代器起始位置到结束位置不包含结束替换为目标串
str.replace(str.begin() 5, str.begin() 7, $$);
assert(hello$$world str);如果想要实现python中替换目标字符或字符串的那种方式得配合find方法先找到目标串的位置然后再进行替换。当然为了提高效率建议还是自己写一个。
字符串截取
std::string str abcdef;
// 从2的位置开始截取到末尾
std::string str2 str.substr(2);
assert(str2 cdef);// 从0的位置开始截取长度为2的子串
str2 str.substr(0, 2);
assert(str2 ab);注意substr不改变调用者自身它会返回一个新的副本也就是str始终没变。
字符串比较
std::string a abcd;
std::string b bcd;// 相等或者不相等可以直接通过或!来比较
assert(a ! b);// 字符串a与b比较
int ret a.compare(b);
assert(ret -1);// 字符串a从1开始长度为3的子串与b比较
ret a.compare(1, 3, b);
assert(ret 0);// 字符串b从0开始长度为3的子串与a从1开始长度为3的子串比较
ret b.compare(0, 3, a, 1, 3);
assert(ret 0);返回值有三种1表示大于-1表示小于0为相等。
字符串与数字相互转换
1. 字符串转化为数字 stoi(const std::string str, std::size_t* pos nullptr, int base 10)
str目标字符串pos传出参数用于接收最后一个非数字的字符位置base进制默认10进制如果为0则按照字符串格式进行解析
只传一个参数时
std::string str 123;
int num std::stoi(str);
assert(num 123);str 123a;
num std::stoi(str);
assert(num 123);str a123;
// 此处会抛出异常invalid_argument
num std::stoi(str);str 12345678901;
// 会抛出异常out_of_range
num std::stoi(str);传入pos
std::string str 111ab1;
size_t pos 0;
int num std::stoi(str, pos);
assert(num 111 pos 3);str 123;
num std::stoi(str, pos);
assert(num 123 pos str.size());可以看出如果需要判断字符串是否完全是由数字组成可以通过pos str.size()来判断。
传入base
std::string str 111;
int num std::stoi(str, nullptr, 2);
assert(num 111b); // 二进制
num std::stoi(str, nullptr, 8);
assert(num 0111); // 八进制
num std::stoi(str, nullptr, 16);
assert(num 0x111); // 十六进制
num std::stoi(str, nullptr, 0);
assert(num 111);str 0111;
num std::stoi(str, nullptr, 0);
assert(num 0111); // 8进制str 0x111;
num std::stoi(str, nullptr, 0);
assert(num 0x111); // 16进制其他转换方法
转换方法返回类型stollongstolllong longstoulunsigned longstoullunsigned long longstoffloatstoddoublestoldlong double
上述返回值为无符号整型时如果传入的字符串是有符号的依然会正常转换只不过转换的结果是有符号数的无符号形式比如-1的无符号形式是0xFFFFFFFF对于32位整型而言。对于浮点型转换是没有进制这个参数的。
2. 数字转化为字符串
数字转化为字符串就相对简单了使用std::to_string即可参数可以是任何数字类型。
字符串分割
分割的方法有很多
通过find方法查找目标分隔符然后利用substr去截取通过c函数strtok或strtok_r进行分割通过stringstream流。
下面只介绍其中一种也就是stringstream流的方式
#include sstream
#include string
#include iostreamint main() {std::string str hello world I love you ;std::stringstream sstream(str);std::string buf;int cnt 0;// 以空格分割while(std::getline(sstream, buf, )) {if (buf.empty()) continue;std::cout cnt : buf std::endl;buf.clear();}return 0;
}执行结果如下
0:hello
1:world
2:I
3:love
4:you注意一定要判断buf为空这种情况否则第一次读到空格时buf将会是一个空值。