title: String
date: 2024-01-10 12:00:00
categories:
- C++
- String
tags: 字符及字符串 #
String
- string有个接收参数为char指针或者const char指针的构造函数
- C++中字符串定义,像是
const char* name = "String";
双引号这种方式的字符串直接为const char*
类型,在c++11中规定不允许char*
来接受这种形式的字符串,在c++11之前是一种未定义的行为,不好的代码风格 - C语言风格的字符串数组定义
char name2[7] = { 'S','t','r','i','n','g',0 };
需要扩充数组补0来告知编译器结束位置否则编译器会被“烫着”(maybe)
就像
这是因为在这种类型的字符定义不像char *
,会有空终止符(the null termination charactor),而是访问到了set cc部分(暂无)
- 传参时如果直接参数传递会使在heap上动态的分配全新的char数组来存储string的复制内容,slow,所以要用引用传递,eg:
void PrintStirng(std::string& string)
常用方法
成员函数 | 说明 |
---|---|
append | 向字符串的末尾添加字符。 |
assign | 对字符串的内容赋新的字符值。 |
at | 返回对字符串中指定位置的元素的引用。 |
begin | 返回发现字符串中第一个元素的位置的迭代器。 |
c_str | 将字符串的内容转换为以 null 结尾的 C 样式字符串。 |
cbegin | 返回发现字符串中第一个元素的位置的常量迭代器。 |
cend | 返回发现字符串中最后一个元素之后的位置的常量迭代器。 |
clear | 清除字符串中的全部元素。 |
compare | 将字符串与指定字符串比较,确定两个字符串是否相等或按字典顺序一个字符串是否小于另一个。 |
copy | 将指定数目的字符从源字符串中的索引位置复制到目标字符组。 已弃用。 请改用 basic_string::_Copy_s 。 |
crbegin | 返回发现反向字符串中第一个元素的位置的常量迭代器。 |
crend | 返回发现反向字符串中最后一个元素之后的位置的常量迭代器。 |
_Copy_s | Microsoft 特定:将指定数目的字符从源字符串中的索引位置复制到目标字符组。 |
data | 将字符串的内容转换为字符数组。 |
empty | 测试字符串是否包含字符。 |
end | 返回发现字符串中最后一个元素之后的位置的迭代器。 |
ends_with C++20 | 检查字符串是否以指定的后缀结尾。 |
erase | 从字符串中的指定位置删除一个或一系列元素。 |
find | 向前搜索字符串,搜索与指定字符序列匹配的第一个子字符串。 |
find_first_not_of | 在字符串中搜索不属于指定字符串中元素的第一个字符。 |
find_first_of | 在字符串中搜索与指定字符串中任何元素匹配的第一个字符。 |
find_last_not_of | 在字符串中搜索不属于指定字符串中任何元素的最后一个字符。 |
find_last_of | 在字符串中搜索属于指定字符串中一个元素的最后一个字符。 |
front | 返回对字符串中第一个元素的引用。 |
get_allocator | 返回用于构造字符串的 allocator 对象的副本。 |
insert | 将一个、多个或一系列元素插入到指定位置的字符串中。 |
length | 返回字符串中元素的当前数目。 |
max_size | 返回字符串可包含的字符的最大数目。 |
rbegin | 返回指向反向字符串中第一个元素的迭代器。 |
rend | 返回指向刚超出反向字符串的最后一个元素的位置的迭代器。 |
replace | 用指定字符或者从其他范围、字符串或 C 字符串复制的字符来替代字符串中指定位置的元素。 |
reserve | 将字符串的容量设置为一个数目,这个数目至少应与指定数目一样大。 |
resize | 根据要求追加或删除元素,为字符串指定新的大小。 |
rfind | 向后搜索字符串,搜索与指定字符序列匹配的第一个子字符串。 |
size | 返回字符串中元素的当前数目。 |
starts_with C++20 | 检查字符串是否以指定的前缀开始。 |
substr | 从字符串起始处的指定位置复制最多某个数目的字符的子字符串。 |
全部代码:
#include <iostream>
#include <string>
void PrintStirng(std::string& string)//直接参数传递会使在heap上动态的分配全新的char数组来存储string的复制内容,slow,所以要用引用传递
{
std::cout << string << std::endl;
}
int main()
{
//char* name = "String";//错误,双引号""来包括字符是指的是const char*类型的字符,所以不能用char*来修饰
const char* name = "String";
//std::string name0="String";
std::string name0 = std::string("string")+"hello";//显示的调用string构造函数将其一个传入string构造函数中
bool contains=name0.find("gh")!=std::string::npos;//查找string中是否有想要查找的内容,有1无0(bool),find;
//name0 += "hello";//连接字符串
//char name2[7] = { 'S','t','r','i','n','g',0 };//需要一个0告知编译器结束位置
std::cout << name << std::endl;
std::cout << name0 << std::endl;//<string>中将"<<"重载,使得可以把字符串传入输出流
std::cout <<contains << std::endl;
PrintStirng(name0);
std::cin.get();
}
String literal
string_literals 是一种在计算机编程中用来表示字符串值的字符序列。字符串值是由一个或多个字符组成的文本,比如 “Hello” 或 “你好”。string_literals 通常用双引号 (") 或单引号 (') 包围,具体取决于编程语言的规则。例如,在 Python 中,“Hello” 和 ‘Hello’ 都是 string_literals。在 C++ 中,“Hello” 是一个 string_literal,但 ‘Hello’ 是一个 character_literal,因为它只包含一个字符。
using namespace std::string_literals; 是一种使用命名空间的方法,它可以让你在代码中方便地使用一些用户自定义的字符串字面量 (string literals)。字符串字面量是一种在计算机编程中用来表示字符串值的字符序列,比如 “Hello” 或 “你好”。用户自定义的字符串字面量是一种通过添加一个后缀 (suffix) 来创建字符串对象的方法,比如 "Hello"s 或 "你好"s。这些后缀可以指定字符串的类型和编码,比如 s 表示 std::string 类型,u8 表示 UTF-8 编码,u16 表示 UTF-16 编码,u32 表示 UTF-32 编码,w 表示宽字符类型12。
std::string_literals 是 C++ 标准库中的一个内联命名空间 (inline namespace),它包含了四种用户自定义的字符串字面量的运算符 (operator),分别是:
- operator""s,用于创建 std::string 类型的字符串字面量,比如 "Hello"s。
- operator""sv,用于创建 std::string_view 类型的字符串字面量,比如 "Hello"sv。
- operator""y,用于创建 std::byte 类型的字符串字面量,比如 "Hello"y。
- operator""z,用于创建 std::size_t 类型的字符串字面量,比如 "123"z3。
当你在代码中使用 using namespace std::string_literals; 时,你就可以直接使用这些后缀来创建字符串对象,而不需要写出完整的命名空间,比如 std::literals::string_literals::operator""s。这样可以节省一些代码的长度和复杂度,也可以提高代码的可读性和可维护性4
不同的编程语言对 string_literals 有不同的处理方式,比如编码、转义、拼接等。编码是指将字符转换为二进制数的过程,不同的编码方式可能导致不同的结果。转义是指使用特殊的字符序列来表示一些无法直接输入的字符,比如换行符、引号、反斜杠等。拼接是指将多个 string_literals 连接成一个更长的 string_literal 的过程,不同的编程语言可能有不同的语法和规则。
下面是一些关于 string_literals 的例子和解释:
-
在 C++ 中,可以使用前缀和后缀来指定 string_literals 的类型和编码。例如,u8"Hello" 表示一个 UTF-8 编码的 string_literal,它的类型是 const char8_t*。L"Hello" 表示一个宽字符 string_literal,它的类型是 const wchar_t*。"Hello"s 表示一个 std::string 类型的 string_literal,它可以使用一些方便的字符串函数1。
-
在 C++ 中,还可以使用原始字符串字面量 (raw string literal) 来表示一些包含转义字符的字符串,比如目录、正则表达式等。原始字符串字面量用 R 前缀和一对括号来表示,括号内的内容就是字符串的内容,不需要转义。例如,R"(C:\Windows\System32)" 表示一个原始字符串字面量,它的内容就是 C:\Windows\System32,不需要将反斜杠转义2。
const char* name = "String";//--utf8
const wchar_t* name2 = L"String";//由编译器决定 window-2B linux-4B
const char16_t* name3 = u"String";//2B,每个字符占16bit--utf16
const char32_t* name4 = U"String"; //4B, 每个字符占32bit--utf32
-
那么我应该用std::string、std::u16string还是std::u32string?
我应该用std::string、std::u16string还是std::u32string? - 知乎 (zhihu.com)
实际操作中会有很多问题,例如:
-
c++中为什么不能std::string name0=“String”+" hello";这样来拼接字符串呢
这是一个很好的问题。在 C++ 中,不能使用 std::string name0=“String”+" hello"; 这样的语句来拼接字符串,因为这样会导致编译错误。原因是,“String” 和 " hello" 都是 const char* 类型的 string_literals,它们不能直接使用 + 号来拼接。+ 号是一个运算符,它需要两个操作数都是 std::string 类型的对象才能进行拼接。如果你想要拼接两个 string_literals,你需要先将它们转换为 std::string 类型,然后再使用 + 号。例如,你可以使用下面的语句来拼接字符串:
std::string name0 = std::string("String") + " hello";
或者,你可以使用一个 string_literal 作为 std::string 的构造函数的参数,然后再使用 + 号。例如,你可以使用下面的语句来拼接字符串:
std::string name0 = "String"s + " hello";
注意,这里的 "String"s 是一个 std::string 类型的 string_literal,因为它使用了 s 后缀。s 后缀是一个用户自定义的字面量 (user-defined literal),它可以将一个 const char* 类型的 string_literal 转换为一个 std::string 类型的 string_literal。
再或者可以
const char* ex=R"(line1 line2 line3 line4)";
适合用大量文本编写,如果没有 R 则需要每个字符串后都\n手动换行,在OpenGL的着色器代码编写时可以用
-
当我用这种方法
std::u32string name0 = U"String"s + U"hello";
来定义了name0后,结果输出name0的时候
std::cout<<name0<<std::endl;
报错:没有找到接受“std::u32string”类型的右操作数的运算符(或没有可接受的转换)。
解决这个问题,可以使用一些第三方的库或者工具来处理 std::u32string 和 std::u16string 的输出问题。比如,可以使用 UTF8-CPP1 或者 Boost.Locale2 来进行编码转换和本地化操作。
other thing
- wstring–宽字符
- basic_string
basic_string 是 C++ 标准库中的一个字符串类模板,它可以用来存储和操作不同类型的字符序列1。basic_string 的完整语法是:
template <class CharType, class Traits = char_traits<CharType>, class Allocator = allocator<CharType>> class basic_string;
其中,CharType 参数表示要存储在字符串中的单个字符的数据类型,比如 char, wchar_t, char16_t, char32_t 等。Traits 参数表示字符的各种重要属性,比如比较、复制、转换等。Allocator 参数表示字符串的内存分配器,用于管理字符串的内存分配和释放2。
C++ 标准库提供了 basic_string 的四种特化,分别是:
- string,用于存储 char 类型的字符,相当于 basic_string。
- wstring,用于存储 wchar_t 类型的字符,相当于 basic_string<wchar_t>。
- u16string,用于存储 char16_t 类型的字符,相当于 basic_string<char16_t>。
- u32string,用于存储 char32_t 类型的字符,相当于 basic_string<char32_t>。
basic_string 类提供了许多用于构造、修改、访问、比较、搜索、替换、拼接等字符串操作的函数和运算符,以及一些用于获取字符串的长度、容量、大小、分配器等信息的函数3。basic_string 类还支持一些用户自定义的字面量,用于方便地创建字符串对象4。
std::string 本质上是basic_string 的char作为模板参数的模板类实例------- 模板特化(template specialization)