C++: C风格字符串

最后更新:2026-08-26

C++ 有两种字符串:

  1. C 风格字符串(字符数组)
  2. C++ string(后面会学)

这一课先学 C 风格字符串——它是 C++ 兼容 C 语言的遗产,理解它有助于理解字符串的底层原理。


1. 什么是 C 风格字符串?

(1) 1.1 本质:字符数组 + 结束符

C 风格字符串就是一个字符数组,但有个特殊规定:

TEXT 📖 仅展示
"Hello" 在内存里是:
+---+---+---+---+---+----+
| H | e | l | l | o | \0 |
+---+---+---+---+---+----+
 0 1 2 3 4 5 ← 下标

💡 重点: C 风格字符串的长度是 5(Hello),但数组大小至少是 6(要存 \0)。



2. 声明与初始化

(1) 2.1 声明 C 风格字符串

语法:

TEXT 📖 仅展示
char 字符串名[大小];

示例:

▶ 示例 2:基础编程实践(难度⭐)

CPP
#include <iostream>

int main() {
 char name[20]; // 能存 19 个字符 + 1 个 \0
 
 name[0] = 'H';
 name[1] = 'e';
 name[2] = 'l';
 name[3] = 'l';
 name[4] = 'o';
 name[5] = '\0'; // 别忘了结束符!
 
 std::cout << "名字:" << name << std::endl; // Hello
 
 return 0;
}
▶ 试一试

输出:

TEXT 📖 仅展示
名字:Hello

💡 提示: 手动加 \0 很麻烦,后面会学更简单的方法。

(2) 2.2 初始化 C 风格字符串

方法一:用字符串字面量初始化

CPP
#include <iostream>

int main() {
 char name = "Hello"; // ✅ 编译器自动加 \0,数组大小是 6
 
 std::cout << "名字:" << name << std::endl;
 
 return 0;
}

💡 重点: 用字符串字面量初始化时,不用写数组大小——编译器会自动计算(包括 \0)。



3. 常用字符串函数

C 风格字符串的函数都在 cstring 头文件里。

(1) 3.1 strlen:计算字符串长度

CPP
#include <iostream>
#include <cstring> // 必须引入这个头文件

int main() {
 char name = "Hello";
 
 std::cout << "字符串:" << name << std::endl;
 std::cout << "长度:" << std::strlen(name) << std::endl; // 5(不包括 \0)
 
 return 0;
}

💡 提示: std::strlen 返回的是有效字符数(不包括 \0),而 sizeof 返回的是数组大小(包括 \0)。

CPP
char name = "Hello";
std::cout << sizeof(name) << std::endl; // 6(数组大小)
std::cout << std::strlen(name) << std::endl; // 5(有效字符数)

(2) 3.2 strcpy:复制字符串

CPP
#include <iostream>
#include <cstring>

int main() {
 char src = "Hello";
 char dest[20];
 
 std::strcpy(dest, src); // 把 src 复制到 dest
 
 std::cout << "src:" << src << std::endl;
 std::cout << "dest:" << dest << std::endl;
 
 return 0;
}

⚠️ 警告: std::strcpy 不会检查目标数组的大小,如果 dest 太小,会缓冲区溢出

更安全的函数(C++11 之后):

CPP
std::strncpy(dest, src, sizeof(dest) - 1); // 最多复制 sizeof(dest)-1 个字符
dest[sizeof(dest) - 1] = '\0'; // 手动加结束符

(3) 3.3 strcat:连接字符串

CPP
#include <iostream>
#include <cstring>

int main() {
 char greeting[50] = "Hello, ";
 char name = "World";
 
 std::strcat(greeting, name); // 把 name 连接到 greeting 后面
 
 std::cout << greeting << std::endl; // Hello, World
 
 return 0;
}

(4) 3.4 strcmp:比较字符串

CPP
#include <iostream>
#include <cstring>

int main() {
 char str1 = "Hello";
 char str2 = "Hello";
 char str3 = "World";
 
 std::cout << "strcmp(str1, str2) = " << std::strcmp(str1, str2) << std::endl;
 std::cout << "strcmp(str1, str3) = " << std::strcmp(str1, str3) << std::endl;
 
 return 0;
}

返回值:

💡 提示: 不要用 == 比较 C 风格字符串!== 比较的是地址,不是内容。

CPP
char str1 = "Hello";
char str2 = "Hello";

if (str1 == str2) { // ❌ 错误:比较的是地址,不是内容
 // ...
}

if (std::strcmp(str1, str2) == 0) { // ✅ 正确:用 strcmp 比较内容
 // ...
}


4. 用 cin 和 cout 处理 C 风格字符串

(1) 4.1 读取字符串

CPP
#include <iostream>

int main() {
 char name[20];
 
 std::cout << "请输入名字:";
 std::cin >> name; // ✅ 可以读取字符串(但不能有空格)
 
 std::cout << "你好," << name << "!" << std::endl;
 
 return 0;
}

💡 问题: cin >> 遇到空格就停止!如果输入 "John Smith",只能读到 "John"

解决方法:用 std::cin.getline

CPP
#include <iostream>

int main() {
 char name[50];
 
 std::cout << "请输入全名:";
 std::cin.getline(name, 50); // ✅ 读取整行(包括空格)
 
 std::cout << "你好," << name << "!" << std::endl;
 
 return 0;
}


5. 实战:简单的字符串处理

▶ 示例 1:统计字符串中元音的个数(难度⭐⭐)

CPP
#include <iostream>
#include <cstring>

int main() {
 char str[100];
 std::cout << "请输入一个字符串:";
 std::cin.getline(str, 100);
 
 int vowels = 0;
 for (int i = 0; i < std::strlen(str); i++) {
 char c = str[i];
 if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' ||
 c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U') {
 vowels++;
 }
 }
 
 std::cout << "元音个数:" << vowels << std::endl;
 
 return 0;
}
▶ 试一试

输出:

TEXT 📖 仅展示
请输入一个字符串:
元音个数:

运行效果:

TEXT 📖 仅展示
请输入一个字符串:Hello World
元音个数:3


6. 常见错误

(1) 6.1 忘记留空间给 \0

错误示例:

CPP
#include <iostream>

int main() {
 char name[5] = "Hello"; // ❌ 错误:"Hello" 需要 6 个字符(包括 \0),但数组大小只有 5
 std::cout << name << std::endl;
 return 0;
}

修复:

CPP
char name[6] = "Hello"; // ✅ 正确:数组大小至少是 6

(2) 6.2 用 = 赋值字符串

错误示例:

CPP
#include <iostream>

int main() {
 char str1[20];
 char str2 = "Hello";
 
 str1 = str2; // ❌ 错误:不能给数组赋值
 str1 = "World"; // ❌ 错误:不能给数组赋值
 
 return 0;
}

修复:用 strcpy

CPP
#include <iostream>
#include <cstring>

int main() {
 char str1[20];
 char str2 = "Hello";
 
 std::strcpy(str1, str2); // ✅ 正确:用 strcpy 复制
 std::cout << str1 << std::endl;
 
 return 0;
}

❓ 常见问题

Q:什么时候用 C 风格字符串,什么时候用 C++ string? A:优先用 C++ string(后面会学),除非: > 1. 你在维护旧代码(C 语言代码) > 2. 你在做极底层的优化(C 风格字符串效率更高)

C++ string 更安全、更易用,推荐新手使用。

Q:为什么 char name = "Hello" 可以,但 int arr = {1, 2, 3} 不行? A:只有字符串字面量能直接用来初始化字符数组。

CPP
char name = "Hello"; // 可以
int arr = {1, 2, 3}; // 可以(这是初始化列表,不是字符串字面量)

Q:怎么把 C 风格字符串转换成 C++ string?

A: 可以直接赋值(C++ string 的构造函数会自动转换)。

CPP
#include `<iostream>`
#include `<string>`

int main() {
    char cstr[] = "Hello";
    std::string cppStr = cstr;  // 自动转换
    
    std::cout << cppStr << std::endl;
    return 0;
}

▶ 示例 3:字符串长度与复制(难度⭐)

CPP
#include <iostream>
#include <cstring>

int main() {
    char src[] = "Hello";
    char dest[20];

    std::cout << "src长度:" << strlen(src) << std::endl;

    strcpy(dest, src);
    std::cout << "复制后:" << dest << std::endl;

    return 0;
}
▶ 试一试

输出:

TEXT 📖 仅展示
src长度:5
复制后:Hello
💡 提示:C风格字符串用 strlen() 获取长度,用 strcpy() 复制。注意目标数组要足够大!


📖 小节


📝 作业

  1. 基础题 (Difficulty ⭐): 声明一个 C 风格字符串 char str = "Hello, World!",输出它的长度和每个字符。

  2. 进阶题 (Difficulty ⭐⭐): 写一个程序,让用户输入两个字符串,比较它们是否相等(用 strcmp)。

  3. 挑战题 (Difficulty ⭐⭐⭐): 写一个程序,实现"字符串反转":

  4. 让用户输入一个字符串

  5. 把它反转(如 "Hello" 变成 "olleH"

  6. 用 C 风格字符串实现(不能用 C++ string)


7. 🚀 下一步

学会了 C 风格字符串,接下来我们学习 C++ string(第19课)—— 更安全、更易用的字符串类!

Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏