跳到主要内容

C++ 字符串声明

介绍

在C++编程中,字符串是最常用的数据类型之一,用于存储和处理文本数据。C++提供了多种处理字符串的方式,从C风格字符串到现代C++的std::string类。本文将详细介绍C++中字符串的声明方式,帮助初学者掌握这一基础而重要的概念。

C++ 中的字符串类型

C++中主要有两种表示字符串的方式:

  1. C风格字符串:源自C语言,本质是字符数组,以空字符'\0'结尾
  2. C++ string类:定义在<string>头文件中,提供了更丰富、更安全的字符串操作功能

C风格字符串声明

C风格字符串实际上是字符数组,末尾有一个空字符'\0'作为结束标志。

基本声明方式

cpp
// 方法1:声明并初始化字符数组
char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};

// 方法2:使用字符串字面量(自动添加'\0')
char message[] = "Hello";

// 方法3:指定大小(确保足够容纳字符串和结束符'\0')
char text[10] = "Hello";

示例代码

cpp
#include <iostream>

int main() {
// 不同的C风格字符串声明
char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
char message[] = "Hello";
char text[10] = "Hello";

// 输出字符串
std::cout << "greeting: " << greeting << std::endl;
std::cout << "message: " << message << std::endl;
std::cout << "text: " << text << std::endl;

return 0;
}

输出:

greeting: Hello
message: Hello
text: Hello
注意

C风格字符串必须以'\0'结尾,否则会导致不可预期的行为!当使用字符串字面量初始化时,编译器会自动添加这个结束符。

std::string类声明

C++的std::string类提供了更安全、更灵活的字符串处理方式,是现代C++推荐使用的字符串类型。

基本声明方式

cpp
#include <string>

// 方法1:默认构造函数(创建空字符串)
std::string str1;

// 方法2:使用字符串字面量初始化
std::string str2 = "Hello";
std::string str3("Hello"); // 另一种初始化语法

// 方法3:复制构造
std::string str4 = str3;

// C++11起的列表初始化
std::string str5 = {"Hello"};

// 从C风格字符串构造
char cstr[] = "Hello";
std::string str6(cstr);

示例代码

cpp
#include <iostream>
#include <string>

int main() {
// 基本声明示例
std::string empty;
std::string hello = "Hello";
std::string world("World");
std::string copy = hello;

// 输出各种字符串
std::cout << "empty: \"" << empty << "\"" << std::endl;
std::cout << "hello: " << hello << std::endl;
std::cout << "world: " << world << std::endl;
std::cout << "copy: " << copy << std::endl;

// 检查字符串长度
std::cout << "hello长度: " << hello.length() << std::endl;

// 字符串拼接
std::string greeting = hello + " " + world + "!";
std::cout << "greeting: " << greeting << std::endl;

return 0;
}

输出:

empty: ""
hello: Hello
world: World
copy: Hello
hello长度: 5
greeting: Hello World!

std::string的更多声明方式

std::string类提供了丰富的构造函数,可以满足各种初始化需求:

cpp
#include <iostream>
#include <string>

int main() {
// 1. 使用重复字符初始化
std::string stars(10, '*'); // 创建包含10个星号的字符串

// 2. 使用子字符串初始化
std::string message = "Hello World";
std::string sub = message.substr(0, 5); // 提取"Hello"

// 3. 从C风格字符串的一部分初始化
char text[] = "C++ Programming";
std::string lang(text, 4); // 取前4个字符:"C++ "

// 4. 从其他string的一部分初始化
std::string programming = "Programming";
std::string prog(programming, 0, 4); // 从索引0开始取4个字符:"Prog"

// 输出所有字符串
std::cout << "stars: " << stars << std::endl;
std::cout << "sub: " << sub << std::endl;
std::cout << "lang: " << lang << std::endl;
std::cout << "prog: " << prog << std::endl;

return 0;
}

输出:

stars: **********
sub: Hello
lang: C++
prog: Prog

std::string与C风格字符串的转换

有时候需要在两种字符串表示之间进行转换,尤其是在调用一些需要C风格字符串的API时。

将std::string转换为C风格字符串

cpp
#include <iostream>
#include <string>
#include <cstring>

int main() {
std::string cppStr = "Hello C++";

// 方法1:c_str()方法(最常用)
const char* cstr1 = cppStr.c_str();

// 方法2:data()方法
const char* cstr2 = cppStr.data();

// 输出结果
std::cout << "原始string: " << cppStr << std::endl;
std::cout << "通过c_str(): " << cstr1 << std::endl;
std::cout << "通过data(): " << cstr2 << std::endl;

return 0;
}

输出:

原始string: Hello C++
通过c_str(): Hello C++
通过data(): Hello C++
注意

从C++11起,data()c_str()都保证返回以空字符结尾的字符数组,但在早期版本中data()不保证以空字符结尾。 此外,这两个方法返回的是指向string内部缓冲区的指针,如果原string被修改,指针指向的内容也会改变。

将C风格字符串转换为std::string

cpp
#include <iostream>
#include <string>

int main() {
// C风格字符串
const char* cstr = "Hello C";

// 转换为std::string
std::string cppStr = cstr; // 直接赋值即可

// 输出结果
std::cout << "原始C字符串: " << cstr << std::endl;
std::cout << "转换后的string: " << cppStr << std::endl;

return 0;
}

输出:

原始C字符串: Hello C
转换后的string: Hello C

字符串声明的实际应用场景

用户输入处理

cpp
#include <iostream>
#include <string>

int main() {
std::string name;

std::cout << "请输入您的姓名: ";
std::getline(std::cin, name); // 读取整行,包括空格

std::string greeting = "欢迎您," + name + "!";
std::cout << greeting << std::endl;

return 0;
}

可能的输出:

请输入您的姓名: 张三
欢迎您,张三!

字符串处理

cpp
#include <iostream>
#include <string>

int main() {
// 声明并初始化文件路径
std::string filePath = "/home/user/documents/report.txt";

// 提取文件名
size_t lastSlash = filePath.find_last_of('/');
std::string fileName = filePath.substr(lastSlash + 1);

// 提取文件扩展名
size_t lastDot = fileName.find_last_of('.');
std::string extension;
if (lastDot != std::string::npos) {
extension = fileName.substr(lastDot);
}

// 输出结果
std::cout << "完整路径: " << filePath << std::endl;
std::cout << "文件名: " << fileName << std::endl;
std::cout << "扩展名: " << extension << std::endl;

return 0;
}

输出:

完整路径: /home/user/documents/report.txt
文件名: report.txt
扩展名: .txt

多语言支持

cpp
#include <iostream>
#include <string>

int main() {
// 支持Unicode字符的字符串(在支持UTF-8的环境中)
std::string chineseGreeting = "你好,世界!";
std::string russianGreeting = "Привет, мир!";
std::string japaneseGreeting = "こんにちは世界!";

// 输出不同语言的问候语
std::cout << "中文问候: " << chineseGreeting << std::endl;
std::cout << "俄语问候: " << russianGreeting << std::endl;
std::cout << "日语问候: " << japaneseGreeting << std::endl;

return 0;
}
提示

在Windows环境中,可能需要设置控制台代码页以正确显示Unicode字符。在Linux/macOS环境中通常默认支持UTF-8。

字符串常量和字面量

C++11引入了多种字符串字面量前缀,用于指定字符串的类型:

cpp
#include <iostream>
#include <string>

int main() {
// 普通字符串字面量
const char* normalStr = "Hello";

// u8前缀:UTF-8编码(C++20前与普通字符串相同)
const char* utf8Str = u8"Hello";

// u前缀:UTF-16编码
const char16_t* utf16Str = u"Hello";

// U前缀:UTF-32编码
const char32_t* utf32Str = U"Hello";

// L前缀:宽字符串
const wchar_t* wideStr = L"Hello";

// R前缀:原始字符串,忽略转义序列
const char* rawStr = R"(C:\Program Files\App)";

// 输出普通字符串和原始字符串
std::cout << "普通字符串: " << normalStr << std::endl;
std::cout << "原始字符串: " << rawStr << std::endl;

return 0;
}

输出:

普通字符串: Hello
原始字符串: C:\Program Files\App

总结

本文详细介绍了C++中的字符串声明方式:

  1. C风格字符串

    • 本质是字符数组,以'\0'结尾
    • 可以通过字符数组或字符串字面量声明
    • 操作较为繁琐且容易出错
  2. std::string类

    • 现代C++推荐使用的字符串类型
    • 提供丰富的构造方式和操作方法
    • 自动管理内存,使用更安全
    • 支持字符串拼接、查找、替换等复杂操作
  3. 两者之间的转换

    • c_str()data()方法转换为C风格字符串
    • 直接赋值可将C风格字符串转换为std::string
  4. 字符串字面量

    • 多种前缀支持不同编码和特性

对于初学者来说,建议优先使用std::string类,它提供了更安全、更直观的字符串处理方式,并且与C++标准库的其他组件能够良好地协同工作。只有在特定场景下(如需要与C API交互)才需要使用C风格字符串。

练习

  1. 编写程序,声明一个std::string变量并初始化为你的全名,然后分别输出姓和名
  2. 声明一个C风格字符串和一个std::string,内容相同,比较它们的使用区别
  3. 编写程序,将用户输入的多行文本存储在string中,直到用户输入空行为止
  4. 实现一个函数,统计给定string中某个字符出现的次数

扩展资源