字符串是存储在内存的连续字节中的一系列字符。
C++处理字符串的方式有两种:
- 来自C语言的C-风格字符串(字符数组)。
- 基于string类的C++库。
1 C-风格字符串
存储在连续字节中的一系列字符意味着可以将字符串存储在char数组中。
要将字符串存储到数组中,常用的方法有两种:
- 将数组初始化为字符串常量
- 将键盘或文件输入读入到数组中
C-风格字符串的特殊性质:以空字符'\0'结尾(ASCII码为0),用来标记字符串的结尾。
- 字符串数组和普通数组处理方式不一样,不应将不是字符串的字符数组当做字符串处理。
- cout打印字符串数组输出时会连续打印字符,直到遇到空字符为止。
- 由于空字符(值设为0)在内存中很常见,因此打印过程很容易很快终止。
具体请参考:C-风格字符串[C++]。
2 string类
ISO/ANSI C++98标准通过添加string类扩展了C++库,可用string类型的变量(其实是对象)来代替字符数组存储字符串。
- string类使用起来比数组简单,它提供将字符串作为一种数据类型的表示方法。
- 要使用string类,必须在程序中包含头文件string。
- string类位于名称空间std中,必须用using编译指令或者std::string来应用它。
- string类定义隐藏了字符串的数组性质,使用户可以像处理普通变量一样处理字符串。
在很多方面,使用string对象的方式与使用字符串数组相同:
- 可以使用C-风格字符串来初始化string对象。
- 可以使用cin来将键盘输入存储到string对象中。
- 可以使用cout来显示string对象。
- 可以使用数组表示方法来访问存储在string对象中的字符。
string对象和字符数组的主要区别:
- 可以将string对象声明为简单变量,而不是数组。
- 类设计让程序能够自动处理string的大小。
- 与使用数组相比,使用string对象更方便,更安全。
- 可以将char数组视为一组用于存储一个字符串的char存储单元,而string类变量则是一个表示字符串的实体。
- 不能将一个数组赋值给另一个数组,但可以将一个string对象赋值给另一个string对象。
具体请参考:string类概述[C++]。
3 其他形式的字符串字面值
C++的字符类型:
- char
- wchar_t:前缀L
- char16_t (C++11):前缀u
- char32_t (C++11):前缀U
- Unicode字符编码方案UTF-8(C++11支持,存储1~4个8位组):前缀u8
- 原始字符串(C++11):前缀R
wchar_t title[] = L"Chief Astrogator";
char16_t name[] = u"Felonia Ripova";
char32_t car[] = U"Humber Super Snipe";
cout << "Jim \"King\" \\n." << '\n';
//输出结果:Jim "King" \n.
cout << R"(Jim "King" \n.)" << '\n';
//输出结果:Jim "King" \n.
原始字符串(C++11)中字符表示的就是自己。
- 无需转义,将"(和)"用作界定符。
- 输入原始字符串时,按回车键不仅会移到下一行,还将在原始字符串中添加回车字符。
- 若要在原始字符串中包含"(和)",可在界定符的"和(之间加其他字符,保证首尾一致。
- 自定义界定符时,在默认界定符间可添加任何基本字符,除了空格、左右括号、斜杠和控制字符(如制表符和换行符)。
cout << R "+*("(Who wouldn't?)", she whispered.)*+" << '\n';
//输出结果:"(Who wouldn't?)", she whispered.
可将前缀R与其他字符串前缀结合使用,如Ru、UR(R前后顺序任意)等表示char16_t类型、char32_t类型的原始字符串。