C++高级 —— String

认识String

string可以说是我们最常用的类,但是其本质不是一个真正的类,而是一个typedef:

using string = std::basic_string<char>;

其是basic_string的特化。basic_string是C++为字符串设计的模板类,采用不同的模板搭配不同的字符类型,可以更有弹性的处理各种文字,常见的特化如下:

using wstring = std::basic_string<wchar_t>;
using u16string = std::basic_string<char16_t>;
using u32string = std::basic_string<char32_t>;


ASCII不支持中文,只有Unicode支持,string就是采用的UTF-8格式支持的中文

使用String

string在C++领域虽然批评的声音很大(主要是成本太高),但是目前来说C++支持它,也没别的可用。在别无选择的情况下,我们就更要了解其优缺点,更好的使用它,以下是常见的用法:

int main()
{
    std::string str = "hello world!";

    str.length();     // 12
    str < "xyz";      //跟strcmp一样的规则
    str.substr(1, 2); //"el"
    str[1];           //'e'
    str.find('l');    //返回下标2
    str += "!!";      //"hello world!!!"
}

字面量

C++14为了方便使用字符串新增了一个字面量字符串后缀's',明确的表示它是string类型的字符串,而不是C字符串,这样就可以利用auto来自动类型推导。详见下面的例子:

#include <string>
#include <iostream>
using namespace std;

using string = std::basic_string<char>;

using namespace std::literals::string_literals; //后缀s必须的命名空间
int main()
{
    auto cstr = "hello world!";
    auto cppstr = "hello world!"s;


    cout << typeid(cstr).name() << endl;        //Point const char
    cout << typeid(cppstr).name() << endl;      //string
}
[ik@localhost test]$ g++ -o test test.cpp 
[ik@localhost test]$ ./test 
PKc
NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE

原始字符串

C++11还为了字面量增加一个原始字符串的新标识形式,比原来的引号多了一个大写字母R和一对圆括号。详见下面的代码:

#include <string>
#include <iostream>
using namespace std;

int main()
{
    auto str = R"(hello world!)";
    cout << str << endl;
}
[ik@localhost test]$ g++ -o test test.cpp 
[ik@localhost test]$ ./test 
hello world!

其好处在于对于转移字符时,我们要打印\n,就必须要转移\\\n,那么在正则表达式中则是更多的\\\\\\n

#include <string>
#include <iostream>
using namespace std;

int main()
{
    auto str1 = R"(\n)";
    auto str2 = "\n";
    auto str3 = "\\\n";
    auto str4 = R"("'"'')";
    auto str5 = "\\\\\\n";

    cout << str1 << endl;
    cout << str2 << endl;
    cout << str3 << endl;
    cout << str4 << endl;
    cout << str5 << endl;
}
[ik@localhost test]$ g++ -o test test.cpp 
[ik@localhost test]$ ./test 
\n


\

"'"''
\\\n

可以看到,这个形式R("xxx"),但是加入说我们要输出这个形式就需要在圆括号两边加上最多16个字符的特别界定符:

#include <string>
#include <iostream>
using namespace std;

int main()
{
    auto str = R"==(R"(xxx)")==";
    cout << str << endl;
}
[ik@localhost test]$ g++ -o test test.cpp 
[ik@localhost test]$ ./test 
R"(xxx)"

字符串转换函数

在处理字符串的时候,我们经常会遇到数字转换为字符串或者字符串转换为数字的需求,除了C函数atoiitoa之外,C++也提供了一系列string的转换函数:

#include <string>
#include <iostream>
using namespace std;

int main()
{
    cout << typeid(stoi("123")).name() << ": " << stoi("123") << endl;
    cout << typeid(stol("123")).name() << ": " << stol("123") << endl;
    cout << typeid(stod("12.3")).name() << ": " << stod("12.3") << endl;
    
    cout << typeid(to_string(123)).name() << ": " << to_string(123) << endl;
}
[ik@localhost test]$ ./test 
i: 123
l: 123
d: 12.3
NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE: 123

字符串视图

字符串String被诟病的主要圆心就是它太重,其在拷贝的时候会发生深拷贝构成。在C++17中,提出了string_view这个类,其是一个字符串视图,只有字符串的指针和这个字符串的长度。所以,string_view在拷贝的时候,只会复制指针变量和长度这两个变量。

 template<typename _CharT, typename _Traits = std::char_traits<_CharT>>
   class basic_string_view
   {
   	...
    private:
      size_t	    _M_len;
      const _CharT* _M_str;
   };
#include <string>
#include <string_view>
#include <iostream>
using namespace std;

int main()
{
    string str = "hello world!";
    string_view strv(str);
    string_view strv_cp = strv;
    cout << strv_cp << endl;
}
[ik@localhost test]$ g++ -std=c++17 -o test test.cpp 
[ik@localhost test]$ ./test 
hello world!

参考文献

[1] 罗剑锋.罗剑锋的C++实战笔记.极客时间

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

shenmingik

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值