目录
Tip:第一次写blog,
1. 概要
C++ String 使用时需添加 #include<string>,其属于 basic_string class 的一个实例,具体有如下几种:
名字 | 描述 |
---|---|
string | String class (class ) |
wstring | Wide string (class ) |
u16string | String of 16-bit characters (class ) |
u32string | String of 32-bit characters (class ) |
字符串读入:
string str;
cin>>s;//读入时以空格分隔
getline(cin,s);//可读入整行
//未知行读入
string s;
while(true){
getline(cin,s);
if(s.length()==0)break;
}
2. 构造、赋值与访问
1.构造、赋值与长度
string 构造函数:
string();//创建一个空的字符串 例如: string str;
string(const string& str);//使用一个string对象初始化另一个string对象
string(const char* s);//使用字符串s初始化
string(int n, char c);//使用n个字符c初始化
string基本赋值操作:
string& operator=(const char* s);//char*类型字符串 赋值给当前的字符串
string& operator=(const string &s);//把字符串s赋给当前的字符串
string& operator=(char c);//字符赋值给当前的字符串
求string的长度用size函数,返回字符串的长度。
2.访问
String 有两种访问方式,一种是类似数组的[]操作,另一种是使用at方法,如s.at(0)。注意,string的下标是从0开始,特别的是,在使用at方法时如果访问越界会出现异常提示。at方法可以检测越界,但效率也会较[]低,具体使用看追求效率还是稳定。
char& operator[](int n);//通过[]方式取字符
char& at(int n);//通过at方法获取字符
3. 比较
①按从左到右的顺序逐字符比较ASCII值,直至出现不等或‘\0’ 注意“13”>“123”
②在其中一个结束比较时,更长的字符串更大,如“1234”>“123”
除了使用重载后的<、>等符号比较之外,string还提供了compare方法,>时返回 1,<时返回 -1,==时返回 0,按字典序排序。
4. 拼接与插入
1.拼接
string重载了包括+, +=, <, =, , [], <<, >>等操作符,所以可以直接与字符串相加,于是可以进行以下操作,其实质是建立了一个临时string变量。
string s1;
s1="123";
s1+="456";
cout<<s1;
此外,string还提供了append方法,其功能是向当前字符串结尾添加新串
string& append(const char *s);//把字符串s(c风格)连接到当前字符串结尾
string& append(const char *s, int n);//把字符串s的前n个字符连接到当前字符串结尾
string& append(const string &s);//同operator+=()
string& append(const string &s, int pos, int n);//把字符串s中从pos开始的n个字符连接到当前字符串结尾
string& append(int n, char c);//在当前字符串结尾添加n个字符c
2.插入
string& insert(size_t pos, const string& str); //在pos前插入子串str
string& insert(size_t pos, const char* s); //和上同,插入c_str字符串
string& insert(size_t pos, const string& str, size_t subpos, size_t sublen);//在pos前插入子串的从subpos开始的sublen位
string&insert (size_t pos,size_t n,char c);//在指定位置插入n个字符c
当pos/subpos超出字符串长度时抛出out_of_range错误
可用 #include <stdexcept>
中的try…catch进行捕获处理
5. 查找与迭代器
c++String的查找函数很多,一共有4*6=24种,如下图所示
名称 | 功能 |
---|---|
find | 查找某子串或字符在待查字符串中第一次出现的位置,并返回(包括0) |
rfind | 功能与find相同,反向查找 |
find_first_of | 在字符串中搜索与参数中任一字符匹配的第一个字符(部分匹配) |
find_last_of | 功能与find_first_of相同,反向查找 |
find_first_not_of | 查找在字符串中缺少的第一个字符 |
find_last_not_of | 查找在字符串中缺少的最后一个字符 |
下面以find为例说明其参数,其余三个与其类似
size_t find (const string& str, size_t pos = 0) const noexcept; //从pos查找str第一次出现的位置
size_t find (const char* s, size_t pos = 0) const;//与上同,s为字符数组
size_t find (const char* s, size_t pos, size_type n) const;//s中从pos开始的前n个字符第一次位置
size_t find (char c, size_t pos = 0) const noexcept;//从pos开始,字符c第一次出现的位置
需要注意的是,上述函数的返回类型均为size_type(无符号),其值为在字符串中出现的位置。当字符不存在时,返回string::nops,其值为-1.
补充:标准库类型将size_type定义为unsigned类型,string::size_type在不同的机器上,长度可以是不同的,并非固定的长度,所以建议使用size_type或auto,而不是int(当然一般做题无所谓)。
关于迭代器,常用的几个有begin(),end(),rbegin().rend(),不过多叙述。
6. 替换
string& replace (size_t pos, size_t len, const string& str);//用str替换string从pos开始的len位
string& replace (iterator i1, iterator i2, const string& str);//用str替换string的[i1,i2)
string& replace (size_t pos, size_t len, const string& str,size_t,subpos, size_t sublen);
//上述三种形式中,const string& str可替换为const char* s或char c(填充)
7. 删除
string& erase (size_t pos = 0, size_t len = npos);//删除从pos开始长度为len的子串,len默认为末尾
iterator erase (iterator first, iterator last);//删除字符串的[first,last)
8. 剪切(提取)
string substr (size_t pos = 0, size_t len = npos) const;//提取字符串从pos开始长度为len的子串
9. 格式转换
1.string转c-style字符串
首先,c风格字符串是指以空字符 null 结束的字符数组,而在c++ 语言中,一般通过const char*类型的指针来操纵 c 风格字符串,如
#include<iostream>
using namespace std;
int main(){
char str1[]={'H','e','l','l','o','\0'};
char str2[]="Hello";//结尾自动加'\0'
const char* stp1=str1;
const char* stp2=str2;
while(*stp1){
putchar(*stp1);
stp1++;
}
return 0;
}
string提供了3个函数用于c字符串转换,这里只讲两种
const char * c_str()const;
const char * data()const noexcept;
上述两个函数中,c_str()直接返回一个以\0结尾的字符串,data()返回的字符串长度、内容与原字符串相同,无\0的字符串(c++11下会加上)
由于c_str()在实现时实际调用了一次data(),所以在追求效率、不考虑是否有结束字符的情况下优先选择使用data()函数,但如果需要使用const char *作为参数,需要使用c_str()函数进行转换。
注意:当修改原字符串时该指针将失效,另外,不可对返回的字符串进行修改
2.string转其它类型
string中提供了许多函数用于string与其它数据类型的转换,共计9种分别为:
int(stoi)、long(stol)、long long(stoll)、unsigned long(stoul)、unsigned long long(stoull)
float(stof)、double(stod)、long double(stold)共计8种
下面以string转int为例,其它8种类似。
string-> int
int stoi (const string& str, size_t* idx = 0, int base = 10);//idx为指针,指向str中第一个不是数字的字符位置 base为进制数
#include<iostream>
#include<string>
using namespace std;
int main(){
string s="11";
cout<<stoi(s);// 输出:11
cout<<stoi(s,nullptr,2);//输出:3 注意,无指针要写nullptr
return 0;
}
除开上述string中提供的函数,<stdio.h>也提供了两个函数有关字符串处理,这里一并讲了
int sprintf(char *str, const char *format, ...)//发送格式化输出到 str 所指向的字符串。
int sscanf(const char *str, const char *format, ...);//从字符串读取格式化输入。
format 标签属性是 %[flags][width][.precision][length]specifier,具体用法与printf和scanf相同。
3.其它类型转string
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 );
10. String流
c++中,输入输出流是指由若干个字节组成的字节序列,这些字节中的数据按顺序从一个对象传送到另一个对象。输出输出流一共有两个基类ios与strembuf类,经过多次继承与派生,有两种类型的字符串流(内存流),均是ostream,istream和iostream类的派生类,以内存中用户定义的字符数组(字符串)为输入输出对象,具体如下:
类名 | 作用 | 头文件 |
---|---|---|
istrstream | 输入字符串流类(基于C类型字符串char*) | strstream |
ostrstream | 输出字符串流类(基于C类型字符串char*) | strstream |
strstream | 输入输出字符串流类(基于C类型字符串char*) | strstream |
strstreambuf | 字符串流缓冲区类(基于C类型字符串char*) | strstream |
istringstream | 输入字符串流类(基于std::string) | sstream |
ostringstream | 输出字符串流类(基于std::string) | sstream |
stringstream | 输入输出字符串流类(基于std::string) | sstream |
stringbuf | 字符串流缓冲区类(基于std::string) | sstream |
可以看到,在c++中有两种字符串流,其功能类似,不过在使用.str()的成员函数时
ostrstream::str()返回的是char*类型的字符串
ostringstream::str()返回的是std::string类型的字符串
一般情况下推荐使用std::string类型的字符串,所以在使用string流时也就推荐使用sstream类,下面简单介绍一下三种流。
1.输入字符串流对象(及从该对象读入)
istringstream的构造函数原型为:
istringstream(ios_base::openmode which = ios_base::in);
istringstream(const string& str,ios_base::openmode which = ios_base::in);
其中,第一条为无参数构造函数,openmode有ios_base::in,ios_base::out,ios_base::ate三种,此处默认为ios_base::in,无需改动。上述语句将建立输入字符串流对象,并与给定的string绑定,从流对象读取数据,以空格为分界符。而正常情况下从与cin绑定的标准I\O设备读取数据。
下面是官方参考文档给出的构造使用参考代码:
// istringstream constructors.
#include <iostream> // std::cout
#include <sstream> // std::istringstream
#include <string> // std::string
int main () {
std::string stringvalues = "125 320 512 750 333";
std::istringstream iss (stringvalues); //创造输入流iss,绑定stringvalues
for (int n=0; n<5; n++)
{
int val;
iss >> val;//从iss读取数据到val
std::cout << val*2 << '\n';
}
return 0;
}
2.输出字符串流对象(及输出至该对象)
ostringstream的构造函数原型为:
ostringstream(ios_base::openmode which = ios_base::out);
ostringstream(const string& str,ios_base::openmode which = ios_base::out);
官方样例:
// ostringstream constructor
#include <iostream> // std::cout, std::ios
#include <sstream> // std::ostringstream
int main () {
std::ostringstream foo; // out
std::ostringstream bar (std::ostringstream::ate); // out|ate
foo.str("Test string");
bar.str("Test string");
foo << 101;
bar << 101;
std::cout << foo.str() << '\n';
std::cout << bar.str() << '\n';
return 0;
}
Output:
101t string
Test string101
3.输入输出字符串流对象
stringstream的构造函数原型为:
stringstream(ios_base::openmode which = ios_base::in | ios_base::out);
stringstream(const string& str,ios_base::openmode which = ios_base::in | ios_base::out);
建立stringstream对象后,可同时使用>>与<<操作,所以一般使用这个对象。有了string流之后,可以直接进行格式转换。