string类的使用
- string类的使用
- 一. string的构造函数的形式
- string类的输入
- 二. string的大小和容量
- 三. string的字符串比较
- 四. string的插入:push_back() 和 insert()
- 五、string拼接字符串:append() 、 +
- 六、 string的遍历:借助迭代器 或者 下标法
- 七、 string的删除:erase()
- 八、 string的字符替换
- 九、string大小写转换:tolower() 和 toupper() 或者 STL中的 transform 算法
- 十、 string的查找:find
- 十一、 string的排序
- 十二、 string的分割/截取字符串:substr()
- 十三、字符串种类
- 十四、字符串与数字之间的转换
- 字符串转整型数字:std::stoi, std::stol, std::stoll
- 字符串转浮点数:stod,stof,stold
- 数字转字符串
string类的使用
必须包含头文件 ,string类是一个模板类,位于名字空间std中。
#include<string>
using std::string;
一. string的构造函数的形式
string str:生成空字符串
string s(str):生成字符串为str的复制品
string s(str, str_begin,str_len):将字符串str中从下标strbegin开始、长度为strlen的部分作为字符串初值
string s(cstr,char_len):以C_string类型cstr的前char_len个字符串作为字符串s的初值
string s(num,char):生成num个c字符的字符串
string s(str,str_index):将字符串str中从下标str_index开始到字符串结束的位置作为字符串初值
string str1; //生成空字符串
str1 = "Hello World!";
string str2(str1); //生成str1的复制品
string str3("12345", 0, 3); //结果为"123"
string str4("012345", 5); //结果为"01234"
string str5(5, '1'); //结果为"11111"
string str6(str2, 6); //结果为"World!"
char alls[] = "All's well that ends well";
string str7(alls,10);//结果为 All's well
string类的输入
二. string的大小和容量
-
size()和length():返回string对象的字符个数,它们执行效果相同。length()成员来自较早版本的string类,而size()则是为提供STL兼容性而设置的。
二者的源代码:
_NODISCARD size_type length() const noexcept { // return length of sequence
return _Get_data()._Mysize;
}
_NODISCARD size_type size() const noexcept { // return length of sequence
return _Get_data()._Mysize;
}
由此可见,二者的底层原理也是相同的。
- max_size():返回string对象最多包含的字符数,超出会抛出length_error异常
- capacity():重新分配内存之前,string对象能包含的最大字符数,返回当前已为字符串分配空间的字符数。
- empty():检查 string 是否无字符.若 string 为空则为 true ,否则为 false 。
string s("Hello World!");
cout << "size=" << s.size() << endl; // size=12
cout << "length=" << s.length() << endl; // length=12
cout << "max_size=" << s.max_size() << endl; // max_size=2147483647
cout << "capacity=" << s.capacity() << endl; // capacity=15
三. string的字符串比较
比较操作符: >, >=, <, <=, ==, !=
这些操作符根据“当前字符特性”将字符按字典顺序进行逐一比较,字典排序靠前的字符小,比较的顺序是从前向后比较,遇到不相等的字符就按这个位置上的两个字符的比较结果确定两个字符串的大小(前面减后面)
成员函数compare()
支持多参数处理,支持用索引值和长度定位子串进行比较,前面减去后面的ASCII码,>0返回1,<0返回-1,相同返回0
str1.compare(str2):compare str1[0, _Mysize) with _Right
str1.compare(_Off, _N0, str2):compare str1[_Off, _Off + _N0) with str2
str1.compare(_Off, _N0, str2, _Roff, _Count):compare str1[_Off, _Off + _N0) with str2[_Roff, _Roff + _Count)
str1.compare(*_Ptr):compare str1[0, _Mysize) with [_Ptr, <null>)
str1.compare(_Off, _N0, *_Ptr, _Count):compare str1[_Off, _Off + _N0) with [_Ptr, _Ptr + _Count)
string A("aBcdf");
string B("AbcdF");
string C("123456");
string D("123dfg");
cout << "(B):" << A.compare(B) << endl; //"aBcdf"和"AbcdF"比较,a>A,返回1
cout << "(2, 2, B):" << A.compare(2, 2, B)<< endl; //"cd"和“AbcdF"比较,c>A,返回1
cout << "(2, 2, B, 2, 2):" << A.compare(2, 2, B, 2, 2) << endl; //"cd"和“cd"比较,返回0
cout << "(0, 4, D, 0, 4):" << C.compare(0, 4, D, 0, 4)<< endl; //"1234"和"123d"比较,返回-1
四. string的插入:push_back() 和 insert()
// 尾插一个字符
s1.push_back('a');
s1.push_back('b');
s1.push_back('c');
cout<<"s1:"<<s1<<endl; // s1:abc
// insert(pos,char):在制定的位置pos前插入字符char
s1.insert(s1.begin(),'1');
cout<<"s1:"<<s1<<endl; // s1:1abc
五、string拼接字符串:append() 、 +
//方法一:append()
string s1("abc");
s1.append("def");
cout<<"s1:"<<s1<<endl; // s1:abcdef
// 方法二:+ 操作符
string s2 = "abc";
/*s2 += "def";*/
string s3 = "def";
s2 += s3.c_str();
cout<<"s2:"<<s2<<endl; // s2:abcdef
六、 string的遍历:借助迭代器 或者 下标法
正向迭代器 ()、()
反向迭代器 ()、()
string s1("abcdef");
// 正向迭代器
string::iterator iter = s1.begin();
for( ; iter < s1.end() ; iter++)
{
cout<<*iter;
}
cout<<endl; //abcdef
// 反向迭代器
string::reverse_iterator riter = s1.rbegin();
for( ; riter < s1.rend() ; riter++)
{
cout<<*riter;
}
cout<<endl; //fedcba
七、 string的删除:erase()
iterator erase(iterator p):删除字符串中p所指的字符
iterator erase(iterator first, iterator last):删除字符串中迭代器区间 [first, last) 上所有字符
string& erase(size_t pos, size_t len):删除字符串中从索引位置 pos 开始的 len 个字符
void clear():删除字符串中所有字符
string s1 = "123456789";
s1.erase(s1.begin() + 1); // 结果:13456789
s1.erase(s1.begin() + 1, s1.end() - 2); // 结果:189
s1.erase(1,6); // 结果:189
八、 string的字符替换
string& replace(size_t pos, size_t n, const char s):将当前字符串从pos索引开始的n个字符,替换成字符串s
string& replace(size_t pos, size_t n, size_t n1, char c):将当前字符串从pos索引开始的n个字符,替换成n1个字符c
string& replace(iterator i1, iterator i2, const char s):将当前字符串[i1,i2)区间中的字符串替换为字符串s
string s1("hello,world!");
s1.replace(6, 5, "girl"); // 结果:hello,girl.
s1.replace(s1.size() - 1, 1, 1, '.'); // 结果:hello,world.
s1.replace(s1.begin(), s1.begin() + 5, "boy"); // 结果:boy,girl.
九、string大小写转换:tolower() 和 toupper() 或者 STL中的 transform 算法
tolower(char) 和 toupper(char) :将字符进行大小写转换
transform(_InIt _First, _InIt _Last, _OutIt _Dest, _Fn1 _Func):transform [_First, _Last) with _Func
string s = "ABCDEFG";
for( int i = 0; i < s.size(); i++ )
{
s[i] = tolower(s[i]);
}
cout << s << endl; //abcdefg
transform(s.begin(), s.end(), s.begin(), ::toupper);
cout << s << endl; //"ABCDEFG"
十、 string的查找:find
string::npos是字符串可存储的最大字符数,通常是无符号int或无符号long的最大取值。如果find函数找不到,则返回string::npos。。查找位置默认从pos=0开始.
find(const string & str,size_type pos = 0) const;
在当前字符串的pos索引位置开始,查找子串str,返回子字符串首次出现时其首字符的索引。
find (const char* s, size_t pos=0):
在当前字符串的pos索引位置开始,查找子串s,返回找到的位置索引
find (const char* s, size_t pos=0,size_type n):
在当前字符串的pos索引位置开始,查找子串s的前n个字符组成的子字符串,返回子字符串首次出现时其首字符的索引。
find (char c, size_t pos=0):
在当前字符串的pos索引位置开始,查找字符c,返回该字符首次出现的位置索引
string类还提供了其他相关方法,它们的重载函数特征标都与find()方法相同:
- rfind() :查找字符串或者字符最后一次出现的位置,也就是从后往前查找,与find()相反。
- find_first_of() :在字符串中查找参数中任何一个字符首次出现的位置。例如,s=“cobra”,"hark"的各个字母在s中首次出现的位置为3(字符r在s中的索引),原理:用s中的每个字符(c,o,b,r,a)按顺序分别与“hark”中的四个字符作对比。字符r首先匹配上,返回其索引。
int where = s.find_first_of("hark");//3
- find_last_of():与find_first_of()功能相同,只是它查找的是最后一次出现的次数。也就是从后往前对比(a,r,b,o,c),结果字符a首先匹配上,返回其在s的索引4;
int where = s.find_last_of("hark");//4
- find_first_no_of():返回字符串中查找第一个不包含在参数中的字符,因此下面的语句将返回字符c在“cobra”中的位置,因为按照(c,o,b,r,a)顺序,c不在“hark”中。
int where = s.find_first_not_of("hark");//0
rfind (const char* s, size_t pos):在当前字符串的pos索引位置开始,反向查找子串s,返回找到的位置索引
rfind (char c,size_t pos):在当前字符串的pos索引位置开始,反向查找字符c,返回找到的位置索引
find_first_of (const char* s, size_t pos):在当前字符串的pos索引位置开始,查找子串s的字符,返回找到的位置索引
find_first_not_of (const char* s, size_t pos):在当前字符串的pos索引位置开始,查找第一个不位于子串s的字符,返回找到的位置索引
find_last_of(const char* s, size_t pos):在当前字符串的pos索引位置开始,向前查找第一个位于子串s的字符,返回找到的位置索引
find_last_not_of (const char* s, size_t pos):在当前字符串的pos索引位置开始,向前查找第一个不位于子串s的字符,返回找到的位置索引
string s("dog bird chicken bird cat");
//字符串查找-----找到后返回首字母在字符串中的下标
// 1. 查找一个字符串
cout << s.find("chicken") << endl; // 结果是:9
// 2. 从下标为6开始找字符'i',返回找到的第一个i的下标
cout << s.find('i', 6) << endl; // 结果是:11
// 3. 从字符串的末尾开始查找字符串,返回的还是首字母在字符串中的下标
cout << s.rfind("chicken") << endl; // 结果是:9
// 4. 从字符串的末尾开始查找字符
cout << s.rfind('i') << endl; // 结果是:18
// 5. 在该字符串中查找第一个属于字符串s的字符
cout << s.find_first_of("13br98") << endl; // 结果是:4("b")
// 6. 在该字符串中查找第一个不属于字符串s的字符,先匹配dog,然后bird匹配不到,所以打印4
cout << s.find_first_not_of("hello dog 2006") << endl; // 结果是:4
// 7. 在该字符串从后往前查找第一个属于字符串s的字符
cout << s.find_last_of("13r98") << endl; // 结果是:19
// 8. 在该字符串从后往前查找第一个不属于字符串s的字符,先匹配tac,然后空格匹配不到,所以打印21
cout << s.find_last_not_of("teac") << endl; // 结果是:21
十一、 string的排序
sort(iterator iter1, iterator iter2):对[iter1, iter2)进行排序
string s = "cdbaef";
sort(s.begin(), s.begin() + 3);
cout << "s:" << s << endl; //s:bcdaef
十二、 string的分割/截取字符串:substr()
string s1("0123456789");
string s2 = s1.substr(2, 5);
cout << s2 << endl; // 结果:23456,参数5表示截取的字符串的长度
string str("I,am,a,student; hello world!");
string split(",; !");
int iCurrentIndex = 0;
int iSplitIndex;
while (iCurrentIndex < str.size()) {
iSplitIndex = str.find_first_of(split, iCurrentIndex);
if (iSplitIndex == -1)
iSplitIndex = str.size();
if (iSplitIndex != iCurrentIndex)
cout << str.substr(iCurrentIndex, iSplitIndex - iCurrentIndex) << endl;
iCurrentIndex = iSplitIndex + 1;
}
/**********************************
结果:
I
am
a
student
hello
world
*/
十三、字符串种类
string库实际上是基于一个basic_string模板类的:
template<class charT, class traits = char _traits<charT>,class Allocator = allocator<charT>>
basic_string{...}
模板basic_string有四个具体化,每一个都有一个typedef名称:
typedef basic_string<char> string;
typedef basic_stirng<wchar_t> wstring;
typedef basic_stirng<char16_t> u16string;
typedef basic_stirng<char32_t> u32string;
十四、字符串与数字之间的转换
字符串转整型数字:std::stoi, std::stol, std::stoll
函数原型:
int stoi( const std::string& str, std::size_t* pos = 0, int base = 10 );
int stoi( const std::wstring& str, std::size_t* pos = 0, int base = 10 );
long stol( const std::string& str, std::size_t* pos = 0, int base = 10 );
long stol( const std::wstring& str, std::size_t* pos = 0, int base = 10 );
long long stoll( const std::string& str, std::size_t* pos = 0, int base = 10 );
long long stoll( const std::wstring& str, std::size_t* pos = 0, int base = 10 );
舍弃所有空白符(以调用 isspace() 鉴别),直到找到首个非空白符,然后取尽可能多的字符组成底 n (其中 n=base )的整数表示,并将它们转换成一个整数值。合法的整数值由下列部分组成:
- (可选)正或负号
- (可选)指示八进制底的前缀( 0 )(仅当底为 8 或 0 时应用)
- (可选)指示十六进制底的前缀( 0x 或 0X)(仅当底为 16 或 0 时应用)
- 一个数字序列
底的合法集是 {0,2,3,…,36} 。合法数字集对于底 2 整数是 {0,1},对于底3整数是 {0,1,2} ,以此类推。对于大于 10 的底,合法数字包含字母字符,从对于底 11 整数的 Aa 到对于底36整数的 Zz 。忽略字符大小写。
若 base 为 0 ,则自动检测数值进制:若前缀为 0 ,则底为八进制,若前缀为 0x 或 0X ,则底为十六进制,否则底为十进制。
若符号是输入序列的一部分,则对从数字序列计算得来的数字值取反,如同用结果类型的一元减。
若 pos 不是空指针,则指针 ptr ——转换函数内部者——将接收 str.c_str() 中首个未转换字符的地址,将计算该字符的下标并存储之于 *pos ,该对象给出转换所处理的字符数。
字符串转浮点数:stod,stof,stold
#include <iostream>
#include<vector>
#include <algorithm>
#include<string>
using namespace std;
int main(void)
{
string str1 = "45";
string str2 = "3.14159";
string str3 = "313.37with words";
string str4 = "words and 2";
int myint1 = stoi(str1);//45
int myint2 = stoi(str2);//3
int myint3 = stoi(str3);//313,可以将字符串最前面的数字提取出来
// 错误: 'std::invalid_argument'
// int myint4 = stoi(str4);
cout << "stoi(\"" << str1 << "\") is " << myint1 << '\n';
cout << "stoi(\"" << str2 << "\") is " << myint2 << '\n';
cout << "stoi(\"" << str3 << "\") is " << myint3 << '\n';
//std::cout << "std::stoi(\"" << str4 << "\") is " << myint4 << '\n';
double mydouble1 = stod(str1);//45
double mydouble2 = stod(str2);//3.14159
double mydouble3 = stod(str3);//313.37
cout << "stod(\"" << str1 << "\") is " << mydouble1 << '\n';
cout << "stod(\"" << str2 << "\") is " << mydouble2 << '\n';
cout << "stod(\"" << str3 << "\") is " << mydouble3 << '\n';
}
/*
stoi("45") is 45
stoi("3.14159") is 3
stoi("313.37with words") is 313
stod("45") is 45
stod("3.14159") is 3.14159
stod("313.37with words") is 313.37*/
参数
- str - 要转换的字符串
- pos - 存储已处理字符数的整数的地址
- base - 数的底
返回值
对应 str 内容的整数值。
数字转字符串
to_string()函数是从C++11开始的。
std::string to_string( int value );
std::string to_string( long value );
std::string to_string( long long value );
std::string to_string( unsigned value );
std::string to_string( unsigned long value );
std::string to_string( unsigned long long value );
std::string to_string( float value );
std::string to_string( double value );
std::string to_string( long double value );
参数
value - 需要转换的数值
返回值
一个包含转换后值的字符串
异常
可能从 std::string 的构造函数抛出 std::bad_alloc 。
注意
- 对于浮点类型, std::to_string 可能产生不期待的结果,因为返回的字符串中的有效位数能为零,见示例。
- 返回值可以明显地有别于 std::cout 所默认打印的结果,见示例。
- std::to_string 由于格式化目的依赖本地环境,从而从多个线程同时调用 std::to_string 可能会导致调用的部分序列化结果。 C++17 提供高性能、不依赖本地环境的替用品 std::to_chars 。
#include <iostream>
#include <string>
int main()
{
double f = 23.43;
double f2 = 1e-9;
double f3 = 1e40;
double f4 = 1e-40;
double f5 = 123456789;
std::string f_str = std::to_string(f);
std::string f_str2 = std::to_string(f2); // 注意:返回 "0.000000"
std::string f_str3 = std::to_string(f3); // 注意:不返回 "1e+40".
std::string f_str4 = std::to_string(f4); // 注意:返回 "0.000000"
std::string f_str5 = std::to_string(f5);
std::cout << "std::cout: " << f << '\n'
<< "to_string: " << f_str << "\n\n"
<< "std::cout: " << f2 << '\n'
<< "to_string: " << f_str2 << "\n\n"
<< "std::cout: " << f3 << '\n'
<< "to_string: " << f_str3 << "\n\n"
<< "std::cout: " << f4 << '\n'
<< "to_string: " << f_str4 << "\n\n"
<< "std::cout: " << f5 << '\n'
<< "to_string: " << f_str5 << '\n';
}
输出结果:
std::cout: 23.43
to_string: 23.430000
std::cout: 1e-09
to_string: 0.000000
std::cout: 1e+40
to_string: 10000000000000000303786028427003666890752.000000
std::cout: 1e-40
to_string: 0.000000
std::cout: 1.23457e+08
to_string: 123456789.000000
参考链接:
/w/cpp/string/basic_string
/p/c86d38db63ce