C++的String类型

1、String 概述:

        string术语定义为:根据C++标准库中“某个string类型(string、wstring、u16string或u32string)”创建出来的object。

        至于寻常由char *或const char *类型所构成的string,称为C-string。

1.1 String Class的目的

        C++标准库中的string class设计的目的就是将string当作一般类型使用而不会令用户感觉到任何问题。可以像对待基础类型那样针对string进行复制、赋值和比较,而再也不必担心内存是否足够、占用的内存实际长度等问题,只需运用操作符,例如以=进行赋值,以==进行比较,以+进行拼接。简而言之,C++标准库对string的设计思路就是,让它的行为尽可能像基础类型,不至于在操作上引起什么麻烦(至少原则如此)。

1.2 String使用的注意事项

(1)、要想使用string,首先要包含“定义有标准C++ string class”的头文件:

#include <string>

 (2)、其次string class被声明于命名空间std

using namespace std;
或者
using std::string;

1.3 String支持的操作函数与参数体制

1.3.1 String支持的操作函数

表1 string支持的操作函数
操作 (Operation)效果(Effect)                                                 
构造函数 (constructor)创建或复制一个string
析构函数(destructor)销毁一个string
=,assign()赋予新值(assign a new value)
swap()交换两个string的内容
+=,append(),push_back()

添加字符

insert()插入字符
erase(),pop_back()删除字符。pop_back()始自C++11
clear()移除全部字符(使之为空)
resize()改变字符数量(在尾端删除或添加字符)
replace()替换字符
+串接string
==,!=,<,<=,>,>=,compare()比较string
empty()判断字符串是否为空
size(),length()返回字符数量
max_size()返回字符的最大可能个数
capacity()返回重分配前的字符容量
reserve()保留一定量内存以容纳一定数量的字符
shrink_to_fit()缩减内存使符合当前的字符量(始自C++11)
[],at()访问某个单一字符
front(),back()访问第一或最末字符(始自C++11)
>>,getline()从一个stream读取某值
<<将某值写入stream
stoi(),stol(),stoll()将string转为带正负号的整数(始自C++11)
stoul(),stoull()将string转为不带正负号的整数(始自C++11)
stof(),stod(),stold()将string转为浮点数(始自C++11)
to_string(),to_wstring()将整数/浮点数转为string(始自C++11)
copy()将string复制为一个字符array--亦即C-string
data(),c_str()将string内容以C-string形式返回
substr()返回某个子字符串(substring)
find functions查找某个字符串(substring)或字符
begin(),end()提供正常的(normal)iterator支持
cbegin(),cend()提供const iterator支持(始自C++11)
rbegin(),rend()提供reverse iterator支持
crbegin(),crend()提供const reverse iterator支持(始自C++11)
get_allocator()返回分配器(allocator)

1.3.2 String操作函数的参数体制

        表1列出了针对string而设计的所有操作函数,STL提供了很多字符串操作函数,其中许多往往具有重载版本,分别以一、二或三个实参来指定新值。表2整理出了所有字符串操作的实参规格。

表2 String操作的实参体制
实参(Argument)含义
const string &str整个string str
const string &str, size_type idx, size_type num通常是指string str中从idx开始的num个字符
const char *cstr整个C-string cstr
const char *chars, size_type len字符数组chars中的len个字符
char c字符c
size_type num, char cnum个字符c
const_iterator beg, const_iterator end区间[beg, end)内的所有字符
initlistinitlist内的所有字符(始自C++11)

1.3.3 String各操作函数支持的参数体制

Full StringPart of String

C-string

(char   *)

char Array

Single

char

num

chars

Iterator

Range

Initlist
构造函数 Yes YesYesYes----YesYesYes

=


assign

Yes----Yes----Yes--------Yes
YesYesYesYes----YesYesYes

+=


append()


push_back()

Yes----Yes----Yes--------Yes
YesYesYesYes----YesYesYes
----------------Yes------------
insert() for idxYesYesYesYes----Yes--------
insert() for iter----------------YesYesYesYes
find(查找)函数Yes----YesYesYes------------
+Yes----Yes----Yes------------
==,!=,<,<=,>,>=Yes----Yes--------------------
compare()YesYesYesYes----------------

2、构造函数和析构函数(Constructor and Destructor)

函数原型:

string::string()

作用:

  • Default构造函数。
  • 创建一个空的string。

函数原型:

string::string(const string &str)

作用:

  • Copy(拷贝)构造函数
  • 建立一个新的string,是str的拷贝(副本)。

函数原型:

string::string(string &&str)

作用:

  • Move(移动)构造函数。
  • 建立一个新的string,以既有的string str的元素为初值。
  • 执行之后,str的内容不明确。
  • 始自C++11。

函数原型:

string::string(const string &str, size_type str_idx)
string::string(const string &str, size_type str_idx, size_type str_num)

作用:

  • 建立一个新string,其初值为“str之内从索引str_idx开始的最多str_num个字符”。
  • 如果没有指定str_num,则取“从str_idx开始到str末尾”的所有字符。
  • 如果str_idx>str.size(),则抛出out_of_range异常。

函数原型:

string::string(const char *cstr)

作用:

  • 建立一个string,以C-string cstr为初值
  • 初值为cstr内“以'\0'为结束符(但不包括'\0')”的所有字符。
  • cstr不可以是null pointer(nullptr或NULL),否则会导致不确定的行为。
  • 如果所得结果超出最大字符数,抛出length_error异常。

函数原型:

string::string(const char *chars, size_type chars_len)

作用:

  • 建立一个string,以字符数组chars内的chars_len个字符为初值。
  • chars必须至少包含chars_len个字符。这些字符可以为任意值,'\0'无特殊意义。
  • 如果chars_len等于string::npos,抛出length_error异常。
  • 如果所得结果超出最大字符数,抛出length_error异常。

函数原型:

string::string(size_type num, char c)

作用:

  • 建立一个string,初值为num个字符c。
  • 如果num等于string::npos,抛出length_error异常。
  • 如果所得结果超出最大字符数,抛出length_error异常。

函数原型:

string::string(InputIterator beg, InputIterator end)

作用:

  • 建立一个字符串,以[beg, end)区间内的字符为初值。
  • 如果所得结果超出最大字符数,抛出length_error异常。

函数原型:

string::string(initializer-list)

作用:

  • 建立一个新的string,以initializer-list的字符为初值。
  • 始自C++11。
  • 如果所得结果超出最大字符数,抛出length_error异常。

函数原型:

string::~string()

作用:

  • 析构函数。
  • 销毁所有字符并释放内存。

2、查找(Seraching and Finding)

2.1、查找单一字符(Find a Character)

函数原型:

size_type string::find(char c) const
size_type string::find(char c, size_type idx) const
size_type string::rfind(char c) const
size_type string::rfind(char c, size_type idx) const

作用:这些函数(从索引idx开始)搜索第一个或最后一个字符c。

           函数find()正向(forward)查找,并返回找到的第一个字符c。

           函数rfind()反向(backward)搜索,并返回找到的最后一个字符c。

返回值:如果成功,就返回字符c的索引;否则返回sring::npos

2.2、查找子字符串(Find a Substring)

函数原型:

size_type string::find(const string &str) const
size_type string::find(const string &str, size_type idx) const
size_type string::rfind(const string &str) const
size_type string::rfind(const string &str, size_type idx) const

作用:这些函数(从索引idx开始)查找第一个或最后一个substring srt

           函数find()正向(forward)查找,并返回第一个substring

           函数rfind()反向(backward)搜索,并返回找到的最后一个substring

返回值:如果成功,就返回substring内的第一字符的索引;否则返回string::npos

函数原型:  

size_type string::find(const char *cstr) const
size_type string::find(const char *cstr, size_type idx) const
size_type string::rfind(const char *cstr) const
size_type string::rfind(const char *cstr, size_type idx) const

作用:这些函数(从索引idx开始)查找“与C-string cstr 内容相同”的第一个或最后一个substring。

          函数find()正向(forward)查找,并返回找到的第一个substring。

          函数rfind()反向(backward)搜索,并返回找到的最后一个substring。

返回值:如果成功,就返回substring内的第一字符的索引;否则返回string::npos

注意:cstr不可以是null pointer(nullptr或NULL),否则会导致不确定的行为。

函数原型:

size_type string::find(const char *chars, size_type idx, size_type chars_len) const
size_type string::rfind(const char *chars, size_type idx, size_type chars_len) const

作用:这些函数(从索引idx开始)查找“与字符数组chars内的chars_len个字符内容相同”的第一个或最后一个子字符串。

          函数find()正向(forward)查找,并返回找到的第一个substring。

          函数rfind()反向(backward)搜索,并返回找到的最后一个substring。

返回值:如果成功,就返回substring内的第一个字符的索引;否则返回string::npos。

注意:chars必须至少包含chars_len个字符。这些字符可以为任意值,'\0'无特殊意义。

2.3、查找第一个符合条件的字符       

函数原型:

size_type string::find_first_of(const string &str) const
size_type string::find_first_of(const string &str, size_type idx) const
size_type string::find_first_not_of(const string &str) const
size_type string::find_first_not_of(const string &str, size_type idx) const

作用:这些函数(从索引idx出开始)查找*this之中属于(或不属于)str的第一个字符。

返回值:如果成功就返回“找到的substring或字符”的索引;否则返回string::npos

函数原型:

size_type string::find_first_of(const char *cstr) const
size_type string::find_first_of(const char *cstr, size_type idx) const
size_type string::find_first_not_of(const char *cstr) const
size_type string::find_first_not_of(const char *cstr, size_type idx) const

作用:这些函数(从索引idx出开始)查找*this之中属于(或不属于) C-string cstr的第一个字符。

返回值:如果成功就返回字符索引;否则返回string::npos。

注意:cstr不可以是null pointer(nullptr 或 NULL),否则会导致不确定的行为。

函数原型:

size_type string::find_first_of(const char *chars, size_type idx, size_type chars_len) const
size_type string::find_first_not_of(const char *chars, size_type idx, size_type chars_len) const

作用:这些函数从索引idx处开始查找*this之中“属于(或不属于)字符数组chars内的前chars_len个字符”的第一个字符。

返回值:如果成功,就返回找到的字符的索引;否则返回string::npos

注意:chars必须至少包含chars_len个字符。这些字符可以为任意值,'\0'无特殊意义。

函数原型:

size_type string::find_first_of(char c) const
size_type string::find_first_of(char c, size_type idx) const
size_type string::find_first_not_of(char c) const
size_tyep string::find_first_not_of(char c, size_type idx) const

作用:这些函数(从索引idx处开始)查找*this之中等于(或不等于)字符c的第一个字符。

返回值:如果成功,就返回找到的字符的索引;否则返回string::npos

2.4、查找最后一个符合条件的字符

函数原型:

size_type string::find_last_of(const string &str) const
size_type string::find_last_of(const string &str, size_type idx) const
size_type string::find_last_not_of(const string &str) const
size_type string::find_last_not_of(const string &str, size_type idx) const

作用:这些函数(从索引idx处开始)查找*this之中属于(或不属于)str的最后一个字符。

返回值:如果成功就返回“找到的substring或字符”的索引;否则返回string::npos

函数原型:

size_type string::find_last_of(const char *cstr) const
size_type string::find_last_of(const char *cstr, size_type idx) const
size_type string::find_last_not_of(const char *cstr) const
size_type string::find_last_not_of(const char *cstr, size_type idx) const

作用:这些函数(从索引idx处开始)查找*this之中属于(或不属于)C-string cstr的最后一个字符。

返回值:如果成功就返回字符索引;否则返回string::npos

注意:cstr不可以是null pointer(nullptr或NULL),否则会导致不确定的行为。

函数原型:

size_type string::find_last_of(const char *chars, size_type idx, size_type chars_len) const
size_type string::find_last_not_of(const char* chars, size_type idx, size_type chars_len) const

作用:这些函数从索引idx处开始查找*this之中“属于(或不属于)字符数组chars内的前chars_len个字符”的最后一个字符。

返回值:如果成功,就返回找到的字符的索引;否则返回string::npos

注意:chars必须至少包含chars_len个字符。这些字符可以为任意值,'\0'无特殊意义。

函数原型:

size_type string::find_last_of(char c) const
size_type string::find_last_of(char c, size_type idx) const
size_type string::find_last_not_of(char c) const
size_type string::find_last_not_of(char c, size_type idx) const

作用:这些函数(从索引idx处开始)查找*this之中等于(或不等于)字符c的最后一个字符。

返回值:如果成功,就返回找到的字符的索引;否则返回string::npos

2.5 npos的意义 

        如果查找函数失败,会返回string::npos。试看下面的例子:

std::string s;
std::string::size_type idx;    // be careful:don't use any other type!
...
idx = s.find("substring");
if (idx == std::string::npos) {
    ...
}

        只有当"substring"不是string s的子字符串时,上面的if语句才会得到true值。

        使用string的npos值及其类型时要格外小心:若要检查函数返回值,一定要使用类型string::size_type,不能以int或unsigned作为返回值类型;否则返回值与string::npos之间的比较可能无法正确执行。这是因为npos被设计为-1:

namespace std {
    template <typename charT,
              typename traits = char_traits<charT>,
              typename Allocator = allocator<charT> >

    class basic_string {
    public:
        typedef typename Allocator::size_type size_type;
        ...
        static const size_type npos = -1;
    };
}

         不幸的是size_type(由string的分配器定义出)必须是个无正负号整数类型,因为default分配器是以size_t作为size_type)。于是-1被转换为无正负号整数类型,npos也就成了该类型的最大无正负号值。然而实际值取决于类型size_type的真实定义。不幸的是这些最大值都不相同。事实上(unsigned long)-1和(unsigned short)-1不同(如果两个类型的大小不同)。因此,对于以下表达式:

idx == std::string::npos

         如果idx的值为-1,由于idx和字符串string::npos类型不同,比较结果可能会是false:

std::string s;
...
int idx = s.find("not found");    // assume it returns npos
if (idx == std::string::npos) {   // ERROR:comparison might not work
    ...
}

        避免这种错误的办法之一就是直接检查查找是否失败:

if (s.find("hi") == std::string::npos) {
    ...
}

        但由于常常需要用到匹配的(查找到的)字符的位置索引,所以另一个简单的解决方法是自行定义对应于npos的带正负号数值:

const int NPOS = -1;

        前述的比较式必须略加修改,但方便多了:

if (idx == NPOS) {    // works almost always
    ...
}

         遗憾的是如果idx的类型为unsigned short,抑或索引大于int最大值,上述比较式就会失败,所以这种解决方案并不完善(也因此,C++ standard并没有按这种方式定义)。但是这两种情况很少发生,所以解决方法在大多数情况下都有效。如果希望代码有高度移植性,则应该对string的任何索引都采用string::size_type。

3、子字符串(Substring)

函数原型:

string string::substr(size_type idx, size_type len) const
string string::substr(size_type idx) const
string string::substr() const

作用:这几种形式都返回*this之中“从索引idx开始的最多len个字符”所组成的substring。

返回值:

        (1)、如果没有len,则将“余下的所有字符”当作substring返回。

        (2)、如果没有idx和len,则返回string拷贝(副本)。

注意:如果idx > size(),则抛出out_of_range异常。

4、字符串的拼接

函数原型:

string operator+(const string &str1, const string &str2)
string operator+(string &&str1, string &&str2)
string operator+(string &&str1, const string &str2)
string operator+(const string &str1, string &&str2)
string operator+(const string &str1, const char *cstr)
string operator+(string &&str, const char *cstr)
string operator+(const char *cstr, const string &str)
string operator+(const char *cstr, string &&str)
string operator+(const string &str, char c)
string operator+(string &&str, char c)
string operator+(char c, const string &str)
string operator+(char c, string &&str)

 作用:所有形式都接合两个操作数内的所有字符,并返回接合后的string。

            只要任何实参是个rvalue reference,其move语义就会被用上,那意味着操作完成后该实参的内容不再明确。

操作数可以是下列任意一种:

        (1)、一个string

        (2)、一个C-string

        (3)、单一字符

注意:由上述函数原型可知,必须确保每个加法运算符(+)的两侧的运算对象至少有一个是string

同时如果结合结果超过最大字符数,则所有形式都抛出length_error异常。

4、

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值