C++中的字符串
string
string的接口比较复杂,除了字符串的操作,还有类似于容器的操作,比如size()、begin()、end()、push_back() 注意:字符串和容器完全是两个不同的概念。 using string = std::basic_string; // string其实是一个类型别名
using string = std::basic_string<char>; // string其实是一个类型别名
基于各种原因:在涉及 Unicode、编码转换的时候,尽量不要用 C++,一般只用string就好。
如果只是存储字符,没有string其他不必要的操作,可以使用vector来代替
使用技巧:
1. 字面量后缀s
using namespace std::literals::string_literals;
auto str = "std string"s;
assert("time"s.size() == 4);
C++14中的新增,字符串后面+s,表示:它是string字符串类型,不是C字符串,可以用auto自动类型推导,而且在其他用到字符串的地方,也可以省去声明临时字符串变量的麻烦,效率也会更高。
注意:为了避免与用户自定义字面量的冲突,后缀“s”不能直接使用,必须用 using 打开名字空间才行
2. 原始字符串R"()"
C++11新增原始字符串内容,将具有转义的字符表达出来。 举例:
auto str1 = R"(char""'')";
auto str2 = R"(\r\n\t\")";
auto str3 = R"(\\\$)";
auto str4 = "\\\\\\$";
如上述表示**R"()"**里括号的内容里放具有转义语义的字符可以直接输出,可轻松表达正则式,或者类似的回车、空格等不可打印的字符\n \r之类的。
但如果表示R"()"呢? 解决办法如下:
auto str5 = R"==(R"(xxx)")==";
3. 字符串转换函数
C++11新增如下转换函数: stoi()、stol()、stoll() 等把字符串转换成整数; stof()、stod() 等把字符串转换成浮点数; to_string() 把整数、浮点数转换成字符串。
assert(stoi("42") == 42);
assert(stol("253") == 253L);
assert(stod("2.0") == 2.0);
assert(to_string(1984) == "1984");
C语言中有atoi()、atol()函数,但是针对的是C语言中的字符串,而不是string,用起来麻烦。
4. 字符串视图类
string 的成本问题。它确实有点“重”,大字符串的拷贝、修改代价很高,所以我们通常都尽量用 const string&,但有的时候还是无法避免(比如使用 C 字符串、获取子串)
C++17 里,string_view,它是一个字符串的视图,成本很低,内部只保存一个指针和长度,无论是拷贝,还是修改,都非常廉价。
可以实现一个在C++11里简化版本
class my_string_view final
{
public:
using this_type = my_string_view;
using string_type = std::string;
using string_ref_type = const std::string&;
using char_ptr_type = const char*;
using size_type = size_t;
private:
char_ptr_type ptr = nullptr;
size_type len = 0;
public:
my_string_view() = default;
~my_string_view() = default;
my_string_view(string_ref_type str) noexcept
: ptr(str.data()), len(str.length())
{}
public:
char_ptr_type data() const
{
return ptr;
}
size_type size() const
{
return len;
}
};
|