2.1动态字符串
文章目录
1.C风格字符串
略
2.字符串字面量(string literal)
字符串字面量实际上存储在内存的只读部分。通过这种方式,编译器可重用等效字符串字面量的引用,从而优化内存的使用。
原始字符串字面量(raw string literal)
原始字符串字面量是可横跨多行代码的字符串字面量,不需要转义嵌入的双引号,像t和n这种转义序列不按照转义序列的方式处理,而是按照普通文本的方式处理。原始字符串字面量以R"(
开头,以)"
结尾。
const char* str {R"(Hello, "world"!)"};
使用原始字符串字面量,不使用n转义序列来开始一个新行,只需要在源代码中按下 Enter 键以开始一个真正的新行。在原始字符串字面量中忽略了转义序列。
因为原始字符串字面量以)"
结尾,所以使用这种语法时,不能在字符串中嵌入)"
。如果需要嵌入)"
,则需要使用扩展的原始字符串字面量语法:
R"d-char-sequence(r-char-sequence)d-char-seguence"
其中,r-char-sequence
是实际的原始字符串,d-char-sequence
是可选的分隔符序列,原始字符串首尾的分隔符序列应保持一致。分隔符序列最多能有16个字符。应选择未出现在原始字符串字面量中的序列作为分隔符序列。
const char* str {R"-(Embedded )" characters)-"};
在操作数据库查询字符串、正则表达式和文件路径时,原始字符串字面量可以令程序的编写更加方便。
3.C++ std::string类
参考链接:std::basic_string - cppreference.com
3.1C风格字符串的问题
略
3.2使用string类
字符串比较
std::string::compare()
方法
如果只想检查两个字符串是否相等,不要使用compare()
,只需要使用==
。
string类支持三向比较符<=>
内存处理
所有string对象都创建为堆中的变量。
与C风格字符串的兼容
为达到兼容的目的,还可应用 string 类的c_str()
方法获得一个表示C 风格字符串的const char
指针。不过,一旦string执行任何内存重分配或string 对象被销毁了,返回的这个const指针就失效了。应该在使用结果之前调用这个方法,以便它准确反映 string当前的内容。永远不要从函数中返回在基于栈的 string 上调用c_str()
的结果。
还有一个data()
方法,在C+14及更早的版本中,始终与c_str()
一样返回 const char*
*。从C+17开始,在非const 字符串上调用时,data()
返回 char*
。
string上的操作
substr(pos,len)
:返回从给定位置开始的给定长度的子字符串。find(str)
:如果找到了给定的子串,返回它的位置,否则,返回string::npos
。replace(pos,len,str)
:将字符串的一部分(给定开始位置和长度)替换为另一个字符串。starts_with(str)
/ends_with()
:如果一个字符串以给定的子串开始或结尾,则返回true
。(From C++20)
从C++20开始,std::string
是constexpr 类。这意味着 string可用于在编译时执行操作,并可用于 constexpr 函数和类的实现。
3.3std::string字面量
源代码中的字符串字面量通常解释为 const char*
。使用用户定义的标准字面量s
可以把字符串字
面量解释为 std::string
。
auto str1{"hello, world"}; //str1 is a const char*
auto str2{"hello, world"s}; //str2 is a std::string
标准用户定义字面量s
在 std::literals::string_literals
名称空间中定义。但是,string::literals
和 literals
名称空间都是所谓的内联名称空间。因此,使用以下选项可以使这些字符串字面量可用于你的代码。
using namespace std;
using namespace std::literals;
using namespace std::string_literals;
using namespace std::literals::string_literals;
基本上,在内联名称空间中声明的所有内容都会自动在父名称空间中可用。要自己定义内联名称空间,可以使用inline
关键字。
3.4std::vector和字符串的CTAD
略
4.数值转换
4.1高级数值转换函数
数值转换为字符串
string std::to_string(T val)
T可以是任意数值类型
字符串转换为数值
通过下面这组同样在 std 名称空间中定义的函数,可以将字符串转换为数值。在这些函数原型中,str
表示要转换的字符串,idx
是一个指针,这个指针接收第一个未转换的字符的索引,base
表示转换过程中使用的进制。idx
指针可以是空指针,如果是空指针,则被忽略。如果不能执行任何转换,这些函数会抛出invalid _argument
异常。如果转换的值超出返回类型的范围,则抛出 out_of_range
异常。
int stoi(const string& str,size_t* idx=0, int base=10);
long stol(const string& str,size_t* idx=0, int base=10);
unsigned long stoul(const string& str,size_t* idx=0, int base=10);
long long stoll(const string& str,size_t* idx=0, int base=10);
unsigned long long stoull(const string& str,size_t* idx=0, int base=10);
float stof(const string& str, size_t* idx=0);
double stod(const string& str, size_t* idx=0);
long double stold(const string& str, size_t* idx=0);
stoi()
、stol()
、stoul()
、stoll()
和 stoull()
接收整数值并且有一个名为 base
的参数,表明了给定的数值应该用什么进制来表示。base 的默认值为10,采用数字为0~9的十进制,base为16表示采用十六进制。如果 base 被设为0,函数会按照以下规则自动计算给定数字的进制。
● 如果数字以0x
或者0X
开头,则被解析为十六进制数字。
● 如果数字以0
开头,则被解析为八进制数字。
● 其他情况下,被解析为十进制数字。
4.2低级数值转换
定义于<charconv>
中
数值转换为字符串
待补充
字符串转换为数值
待补充
5. std::string_view类
std::string_view
类是std::basic_string_view
类模板的实例化,在<string_view>
中定义。string_view
基本上就是 const string&
的简单替代品,但不会产生开销。它从不复制字符串,string_view
支持与 std::string
类似的接口。一个例外是缺少 c_str()
,但 data()
是可用的。另外,string_view
添加了 remove_prefix(size_t)
和remove_suffix(size_t)
方法,前者将起始指针前移给定的偏移量来收缩字符串,后者则将结尾指针倒退给定的偏移量来收缩字符串。
常按值传递 string_views,因为它们的复制成本极低。它们只包含指向字符串的指针以及字符串的长度。
还有一个string_view构造函数,它接收任意原始缓冲区和长度,这可用于从字符缓冲区构建string_view。
void func(string_view sv){
// ...
}
int main(){
const char* raw{/* .. */};
size_t length{/* ... */};
func({raw, length});
func(string_view{raw, length});
}
无法从 string_view 隐式构建一个 string。要么使用一个显式的 string 构造函数,要么使用string_view::data()
成员。同样,无法连接一个string和一个string_view,要实现连接可使用append()
方法。
返回字符串的函数应返回const std::string&
或 string
,但不应返回 string_view。返回string_view 会带来使返回的 string_view 无效的风险,例如当它指向的字符串需要重新分配时。
5.1std::string_view与临时字符串
string_view不应该用于保存一个临时字符串的视图。
5.2std::stirng_view字面量
可使用标准的用户定义的字面量sv
,将字符串字面量解释为 std::string_view
。
auto sv{"my string_view"sv};
需要使用以下几条命令之一:
using namespace std;
using namespace std::literals;
using namespace std::string_view_literals;
using namespace std::literals::string_view_literals;
6.非标准字符串
略