C 语言字符串和内存操作函数
strcpy()
、sprintf()
和 memcpy()
都是 C 语言中的标准库函数,用于 字符串复制、格式化字符串和内存拷贝。它们的功能和适用场景不同:
函数 | 作用 | 适用于 |
---|---|---|
strcpy() | 复制 C 字符串 | 复制 char* 类型的字符串 |
sprintf() | 格式化字符串并存入缓冲区 | 生成字符串,类似 printf() |
memcpy() | 拷贝内存(可以拷贝任意数据) | 复制二进制数据或结构体 |
1. strcpy()
:复制 C 字符串
📌 作用
strcpy()
用于复制字符串(char*
),目标缓冲区需要足够大,否则可能导致缓冲区溢出(Buffer Overflow)。
✅ 正确用法
#include <iostream>
#include <cstring>
int main() {
char src[] = "Hello, World!";
char dest[50]; // ✅ 确保足够大
strcpy(dest, src); // ✅ 复制字符串
std::cout << "Copied string: " << dest << std::endl; // 输出 "Hello, World!"
return 0;
}
📌 dest
必须足够大,否则可能导致 strcpy()
访问越界,造成崩溃!
❌ 错误示例(目标空间不够)
char dest[5];
strcpy(dest, "Hello, World!"); // ❌ 越界访问,可能崩溃
📌 应使用 strncpy()
限制复制长度:
strncpy(dest, src, sizeof(dest) - 1);
dest[sizeof(dest) - 1] = '\0'; // ✅ 确保字符串结尾
2. sprintf()
:格式化字符串
📌 作用
sprintf()
类似于printf()
,但它不会输出到屏幕,而是存入char*
缓冲区。- 支持格式化字符串,可用于数字转换、日期格式化等。
✅ 示例
#include <iostream>
#include <cstdio>
int main() {
char buffer[100];
int num = 42;
double pi = 3.14159;
sprintf(buffer, "Number: %d, Pi: %.2f", num, pi);
std::cout << buffer << std::endl; // 输出 "Number: 42, Pi: 3.14"
}
📌 sprintf()
格式化字符串,并存入 buffer
,避免了 strcpy()
的限制。
❌ sprintf()
可能导致缓冲区溢出
char smallBuffer[5];
sprintf(smallBuffer, "This is a long text"); // ❌ 可能溢出
📌 应使用 snprintf()
限制最大字符数
snprintf(smallBuffer, sizeof(smallBuffer), "This is a long text");
3. memcpy()
:拷贝内存
📌 作用
memcpy()
用于拷贝二进制数据(可以是字符串、数组、结构体)。- 比
strcpy()
更通用,可以拷贝非字符串数据(如int
、struct
)。 - 不会自动添加
\0
结尾,必须手动添加。
✅ 示例
#include <iostream>
#include <cstring>
struct Person {
char name[20];
int age;
};
int main() {
Person p1 = { "Alice", 25 };
Person p2;
memcpy(&p2, &p1, sizeof(Person)); // ✅ 复制整个结构体
std::cout << "Name: " << p2.name << ", Age: " << p2.age << std::endl;
}
📌 memcpy()
直接拷贝 struct
,适用于二进制数据复制。
⚠️ memcpy()
不能用于字符串拷贝
char src[] = "Hello";
char dest[10];
memcpy(dest, src, sizeof(src)); // ✅ 复制字符串,但不会自动加 `\0`
📌 如果 src
不是以 \0
结尾,目标 dest
可能不是有效的字符串!
4. strcpy()
vs memcpy()
vs sprintf()
对比
功能 | strcpy() | memcpy() | sprintf() |
---|---|---|---|
拷贝数据类型 | 仅字符串(char* ) | 任意数据(包括二进制) | 格式化字符串 |
是否自动加 \0 | ✅ 是 | ❌ 否 | ✅ 是 |
是否安全 | ❌ 可能溢出 | ✅ 安全(只拷贝指定大小) | ❌ 可能溢出 |
适用场景 | 字符串复制 | 结构体/数组拷贝 | 格式化字符串 |
5. 什么时候使用哪种函数?
场景 | 推荐方法 |
---|---|
复制字符串 | strcpy() (但 strncpy() 更安全) |
格式化字符串 | sprintf() (但 snprintf() 更安全) |
拷贝二进制数据(如 struct ) | memcpy() |
避免缓冲区溢出 | strncpy() / snprintf() |
🚀 C++ 代码建议使用 std::string
代替 strcpy()
,更安全、易用! 🚀