- C++
C++ C风格字符串学习笔记
- 2025-5-14 19:11:30 @
C++ C风格字符串教程
在C++中,C风格字符串是一种基础且重要的数据类型,它实际上是由字符数组构成,以空字符\0
结尾。本教程将带你全面了解C风格字符串的使用方法。
1. C风格字符串的定义与初始化
C风格字符串有多种定义和初始化方式:
#include <iostream>
using namespace std;
int main() {
// 方式1:字符数组初始化
char str1[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
// 方式2:字符串字面量初始化(推荐)
char str2[] = "Hello"; // 编译器自动添加'\0'
// 方式3:指定大小的数组初始化
char str3[10] = "Hello"; // 剩余元素自动初始化为'\0'
// 方式4:指针指向字符串常量(注意:不可修改)
const char* str4 = "Hello";
cout << "str1: " << str1 << endl;
cout << "str2: " << str2 << endl;
cout << "str3: " << str3 << endl;
cout << "str4: " << str4 << endl;
return 0;
}
注意事项:
- 字符串长度 = 可见字符数 + 1(结尾的
\0
) - 使用字符串字面量初始化指针时,不要尝试修改内容
- 字符数组大小应至少比可见字符数多1
2. 输入输出C风格字符串
可以使用cin
和cout
进行C风格字符串的输入输出:
#include <iostream>
using namespace std;
int main() {
char name[20];
cout << "请输入你的名字:";
cin >> name; // 遇到空格或换行符停止读取
cout << "你好," << name << "!" << endl;
// 读取包含空格的字符串
char sentence[100];
cout << "请输入一句话:";
cin.ignore(); // 忽略缓冲区中的换行符
cin.getline(sentence, 100); // 读取整行,最多99个字符
cout << "你输入的是:" << sentence << endl;
return 0;
}
输入函数说明:
cin >> str
:遇到空格或换行符停止cin.getline(str, size)
:读取整行,包含空格cin.ignore()
:忽略缓冲区中的字符
3. C风格字符串常用操作
C++标准库提供了一系列处理C风格字符串的函数,包含在<cstring>
头文件中。
#include <iostream>
#include <cstring> // 包含C风格字符串处理函数
using namespace std;
int main() {
char str1[20] = "Hello";
char str2[20] = "World";
char dest[50];
// 1. 字符串长度
cout << "str1长度:" << strlen(str1) << endl;
// 2. 字符串复制
strcpy(dest, str1); // 复制str1到dest
cout << "复制后dest:" << dest << endl;
// 3. 字符串拼接
strcat(dest, " "); // 拼接空格
strcat(dest, str2); // 拼接str2
cout << "拼接后dest:" << dest << endl;
// 4. 字符串比较
if (strcmp(str1, str2) == 0) {
cout << "str1和str2相等" << endl;
} else {
cout << "str1和str2不相等" << endl;
}
// 5. 查找子字符串
char* pos = strstr(dest, "World");
if (pos != nullptr) {
cout << "'World'出现在位置:" << pos - dest << endl;
}
return 0;
}
常用函数总结:
函数名 | 功能描述 |
---|---|
strlen(s) |
返回字符串s 的长度 |
strcpy(d, s) |
将字符串s 复制到d |
strcat(d, s) |
将字符串s 拼接到d 的末尾 |
strcmp(s1, s2) |
比较s1 和s2 ,返回0表示相等 |
strstr(s, sub) |
在s 中查找子串sub ,返回指针 |
4. 字符串与数字的转换
在C风格字符串中,可以使用以下函数进行字符串与数字的转换:
#include <iostream>
#include <cstdlib> // 包含atoi, atof等函数
using namespace std;
int main() {
// 1. 字符串转整数
char numStr1[] = "12345";
int num1 = atoi(numStr1);
cout << "字符串转整数:" << num1 << endl;
// 2. 字符串转浮点数
char numStr2[] = "3.14159";
double num2 = atof(numStr2);
cout << "字符串转浮点数:" << num2 << endl;
// 3. 整数转字符串(使用sprintf)
char result[20];
int value = 2025;
sprintf(result, "当前年份:%d", value);
cout << "整数转字符串:" << result << endl;
// 4. 浮点数转字符串
double pi = 3.1415926;
sprintf(result, "圆周率:%.4f", pi);
cout << "浮点数转字符串:" << result << endl;
return 0;
}
转换函数说明:
atoi(str)
:将字符串转换为int
atol(str)
:转换为long
atof(str)
:转换为double
sprintf(dest, format, value)
:格式化输出到字符串
5. C风格字符串与C++字符串的转换
C风格字符串与C++的string
类可以相互转换:
#include <iostream>
#include <string> // C++字符串类
using namespace std;
int main() {
// 1. C风格字符串转C++ string
char cStr[] = "Hello C++";
string cppStr = cStr;
cout << "C++ string: " << cppStr << endl;
// 2. C++ string转C风格字符串
string anotherStr = "World";
const char* newCStr = anotherStr.c_str(); // 返回const char*
cout << "C风格字符串: " << newCStr << endl;
// 3. 修改C++ string后,原指针仍然有效
anotherStr += "!";
cout << "修改后的C++ string: " << anotherStr << endl;
cout << "原指针内容: " << newCStr << endl; // 可能失效!
// 4. 安全的转换方式
char buffer[50];
strcpy(buffer, anotherStr.c_str());
cout << "安全复制后的内容: " << buffer << endl;
return 0;
}
转换注意事项:
string.c_str()
返回的指针可能随string
变化而失效- 如需长期保存,建议复制到字符数组中
string
类提供了更安全、方便的字符串操作
6. C风格字符串的常见问题与陷阱
使用C风格字符串时,需要注意以下问题:
#include <iostream>
#include <cstring>
using namespace std;
int main() {
// 问题1:数组越界
char str[5] = "Hello"; // 错误!需要至少6个字符空间
// 问题2:未初始化的字符串
char uninit[10];
cout << uninit << endl; // 可能输出乱码
// 问题3:字符串拼接越界
char dest[6] = "Hello";
strcat(dest, " World"); // 缓冲区溢出!
// 问题4:修改字符串常量
const char* ptr = "Constant";
// ptr[0] = 'c'; // 错误!不能修改常量
// 安全做法:使用足够大的数组
char safeDest[20] = "Hello";
strcat(safeDest, " World");
cout << safeDest << endl;
return 0;
}
安全建议:
- 始终确保字符数组有足够空间
- 初始化字符数组
- 使用更安全的函数如
strncpy
和strncat
- 区分字符串常量和可修改的字符数组
总结
C风格字符串是C++中处理文本的基础方式,理解它的工作原理对学习C++至关重要。本教程涵盖了C风格字符串的定义、输入输出、常用操作、类型转换以及常见问题。在实际编程中,建议优先使用C++的string
类,它提供了更安全、便捷的字符串操作,但C风格字符串在与C语言库交互或性能敏感场景中仍有重要作用。
10 条评论
-
admin SU @ 2025-5-16 10:15:02
C++ 教程:C风格字符串(char数组)详解(0基础通俗易懂)
📚 什么是 C 风格字符串?
在 C++ 中,有两种主要的字符串处理方式:
- C++ 标准库中的
string
类型(如std::string
)——更现代、更安全、推荐使用 - C 风格字符串(字符数组)——底层、灵活、常用于系统编程或与旧代码交互
本教程重点讲解 C 风格字符串(C-style string),也就是我们常说的:
使用字符数组来表示字符串的方式。
🧠 基本概念:字符数组 + '\0' 结束符
示例:
char str[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
这串字符是
'H' 'e' 'l' 'l' 'o'
,最后一个\0
是 字符串结束符,表示“到这里为止”。更常见的写法:
char str[] = "Hello";
编译器会自动帮你加上结尾的
\0
,所以实际长度是6
字符。
🛠️ 常见操作
✅ 定义和初始化
char name[20]; // 定义一个最多放19个字符的字符串(最后要留一个\0) strcpy(name, "Tom"); // 赋值用 strcpy
或者直接初始化:
char name[] = "Tom"; // 自动推断大小为4(T o m \0)
⚠️ 注意:不能这样赋值:
char name[20]; name = "Tom"; // ❌ 错误!不能直接给数组赋值
要用
strcpy()
函数:#include <cstring> strcpy(name, "Tom"); // ✅ 正确
🔍 常用函数(来自
<cstring>
头文件)函数 功能 strcpy(dest, src)
把 src
拷贝到dest
strcat(dest, src)
把 src
拼接到dest
后面strlen(str)
获取字符串长度(不包括 \0
)strcmp(str1, str2)
比较两个字符串是否相等 strchr(str, ch)
在字符串中查找某个字符第一次出现的位置 strstr(str1, str2)
在字符串 str1
中查找子串str2
是否存在
💡 详细讲解几个常用函数
1.
strcpy
:复制字符串#include <iostream> #include <cstring> using namespace std; int main() { char src[] = "Hello World"; char dest[50]; strcpy(dest, src); // 把 src 拷贝到 dest cout << dest << endl; // 输出 Hello World return 0; }
2.
strcat
:拼接字符串char a[50] = "Hello "; char b[] = "World"; strcat(a, b); // 把 b 接到 a 后面 cout << a << endl; // 输出 Hello World
3.
strlen
:获取字符串长度char str[] = "Hello"; cout << strlen(str) << endl; // 输出 5
注意:不包括结尾的
\0
。4.
strcmp
:比较字符串char a[] = "Apple"; char b[] = "Banana"; if (strcmp(a, b) == 0) cout << "相同" << endl; else if (strcmp(a, b) < 0) cout << "a 小于 b" << endl; else cout << "a 大于 b" << endl;
输出:
a 小于 b
因为字母顺序 A < B。
⚠️ 常见错误 & 注意事项
❌ 不检查空间是否足够
char shortStr[5] = "Hi"; // 正确,占3个字符(H i \0) strcpy(shortStr, "Longer"); // ❌ 错误!目标空间不够,导致溢出
👉 解决办法:确保目标数组足够大!
❌ 忘记加
\0
或越界访问字符数组如果不以
\0
结尾,很多字符串函数会崩溃!❌ 试图修改字符串字面量(只读内存)
char* p = "Hello"; // 指向的是只读内存 p[0] = 'h'; // ❌ 运行时错误!不要改字面量内容
✅ 正确做法:
char arr[] = "Hello"; // 数组拷贝了字符串内容 arr[0] = 'h'; // ✅ 可以修改
🧪 示例程序:输入姓名并打招呼
#include <iostream> #include <cstring> using namespace std; int main() { char name[100]; cout << "请输入你的名字:"; cin >> name; // 输入不会带空格的字符串 cout << "你好," << name << "!欢迎学习C语言字符串!" << endl; return 0; }
📌 总结知识点
内容 说明 C风格字符串 是字符数组,以 \0
结尾初始化 char str[] = "Hello";
常用函数 strcpy
,strcat
,strlen
,strcmp
不可变性 字符串字面量不能修改 安全问题 要注意缓冲区溢出(buffer overflow)
🧩 进阶建议
- 学习如何手动实现
strcpy
,strlen
,strcmp
- 学习
strtok
分割字符串 - 学习
sprintf
和sscanf
格式化输入输出 - 学习如何将数字转成字符串(如
itoa
)
📖 推荐对比学习
类型 示例 特点 C风格字符串 char str[100] = "Hello";
底层、灵活、容易出错 C++ string string s = "Hello";
安全、方便、推荐使用
如果你希望我继续扩展以下内容,请告诉我:
- 如何处理带空格的字符串?
- 如何用
fgets
安全读取一行? - 如何实现自己的
my_strcpy
函数? - 如何将整数转为 C 风格字符串?
😊
- C++ 标准库中的
-
2025-5-14 20:32:35@
C++ C风格字符串教程
C风格字符串是C++中用于处理字符串的传统方式,以字符数组的形式存储,并以空字符
\0
结尾。1. 定义和初始化
1.1 字符数组定义
char str1[] = "Hello"; // 自动添加结尾的空字符 char str2[6] = {'H', 'e', 'l', 'l', 'o', '\0'}; // 手动添加空字符
1.2 字符指针定义
char* str3 = "World"; // 指向字符串常量 const char* str4 = "C++"; // 常量字符串指针,防止修改
2. 基本操作
2.1 获取字符串长度
#include <cstring> size_t len = strlen(str); // 返回字符串长度,不包括`\0`
2.2 复制字符串
#include <cstring> char dest[20]; strcpy(dest, src); // 将src复制到dest,需确保dest有足够的空间
2.3 连接字符串
#include <cstring> char str1[20] = "Hello"; char str2[] = " World"; strcat(str1, str2); // 将str2连接到str1的末尾
2.4 比较字符串
#include <cstring> int result = strcmp(str1, str2); // 返回比较结果: // 0:相等 // 小于0:str1小于str2 // 大于0:str1大于str2
3. 注意事项
- 内存管理:需要手动管理内存,防止缓冲区溢出和内存泄漏。
- 空字符:确保字符串以
\0
结尾,否则可能导致未定义行为。 - 安全性:建议使用安全版本的函数,如
strncpy
、strncat
、strncmp
,防止越界访问。
4. 示例
#include <iostream> #include <cstring> int main() { char str1[20] = "Hello"; char str2[20] = "World"; std::cout << "Length of str1: " << strlen(str1) << std::endl; char dest[40]; strcpy(dest, str1); strcat(dest, str2); std::cout << "Concatenated string: " << dest << std::endl; int result = strcmp(str1, str2); if (result == 0) { std::cout << "str1 and str2 are equal" << std::endl; } else if (result < 0) { std::cout << "str1 is less than str2" << std::endl; } else { std::cout << "str1 is greater than str2" << std::endl; } return 0; }
5. 总结
C风格字符串在处理性能要求高或与C代码兼容的场景下仍然有用,但需要注意内存管理和安全性问题。对于大多数现代C++开发,推荐使用
std::string
类,提供更便捷和安全的字符串操作。 -
2025-5-14 20:11:22@
#include<iostream> #include<cstring> using namespace std; int main() { //6换行符 //good morning int n; cin>>n; char ss[300]; //cin.getline(ss,300);// string getline(cin,ss) cin.ignore();//:忽略缓冲区中的字符 cin.getline(ss,300); cout<<n<<" "<<ss<<endl; return 0; }
-
2025-5-14 20:02:23@
#include<iostream> #include<cstring> using namespace std; int main() { //6换行符 //good morning int n; cin>>n; char ss[300]; cin.getline(ss,300);// string getline(cin,ss) cin.getline(ss,300); cout<<n<<" "<<ss<<endl; return 0; }
-
2025-5-14 19:37:01@
#include<iostream> #include<cstring> using namespace std; int main() { char a[300]={}; //cin>>a; cin.getline(a,300); cout<<a<<" "<<strlen(a)<<endl; return 0; }
-
2025-5-14 19:26:05@
-
2025-5-14 19:23:13@
#include<iostream> #include<cstring> using namespace std; int main() { char a[300]={}; //cin>>a; cin.getline(a,300); cout<<a<<endl; return 0; }
-
2025-5-14 19:22:07@
-
2025-5-14 19:19:17@
#include<iostream> using namespace std; int main() { char a[300]={}; cin>>a; cout<<a<<endl; return 0; }
-
2025-5-14 19:11:44@
#include<iostream> using namespace std; int main() { cout<<"hello world"<<endl; cout<<"he\0llo world"<<endl; char a[6]={'h','e','l','l','o','\0'}; char b[6]={"hello"}; char c[6]="hello"; cout<<a<<endl; cout<<b<<endl; cout<<c<<endl; return 0; }
- 1