93人参与 • 2026-05-13 • C/C++
c++中,有个常见的字符串拷贝函数:char* strcpy(char* dst, const char* src), 作用是将1个字符串src,拷贝到另外一个字符串dst。需要考虑的边界条件如下:
#include <cassert>
// 对齐标准strcpy签名,src加const保证常量正确性
char* my_strcpy(char* dst, const char* src) {
// 调试期断言快速定位空指针问题,发布模式可关闭断言不影响性能
assert(dst != nullptr && src != nullptr);
// 保存目标地址首指针,后续会移动dst指针
char* ret = dst;
// 拷贝逻辑:赋值表达式返回赋值后的值,遇到'\0'时循环终止,自动包含结束符
while ((*dst++ = *src++) != '\0');
return ret;
}实现了核心功能,适合调用方能保证参数合法性的高性能场景。
参考memmove的语义,处理重叠场景,特别存在地址重叠的情况(如字符串内部移动)
#include <cstddef> // size_t定义
char* my_strcpy(char* dst, const char* src) {
// 发布期也保留空指针检查,避免程序崩溃
if (dst == nullptr || src == nullptr) {
return nullptr;
}
char* ret = dst;
// 第一步:计算src总长度(包括末尾'\0')
size_t len = 0;
while (src[len] != '\0') len++;
len += 1; // 包含结束符的总拷贝字节数
// 第二步:判断内存重叠,选择拷贝方向
if (dst < src || dst >= src + len) {
// 无重叠 / dst在src前面,从前向后拷贝性能更高
for (size_t i = 0; i < len; i++) {
dst[i] = src[i];
}
} else {
// 重叠且dst在src后面,从后向前拷贝避免覆盖未读取的src内容
// 注意:size_t是无符号类型,禁止写i>=0(永远为真),改为从len倒序到1
for (size_t i = len; i > 0; i--) {
dst[i-1] = src[i-1];
}
}
return ret;
}在实际开发中,禁止使用无长度限制的strcpy,推荐实现带缓冲区长度的安全版本,彻底避免溢出:
#include <cstddef>
char* my_strcpy_s(char* dst, size_t dst_size, const char* src) {
if (dst == nullptr || src == nullptr || dst_size == 0) {
return nullptr;
}
size_t i = 0;
// 最多拷贝dst_size-1个字符,预留1个位置给'\0'
while (src[i] != '\0' && i < dst_size - 1) {
dst[i] = src[i];
i++;
}
// 强制加结束符,保证dst永远是合法c字符串(解决strncpy不自动加'\0'的缺陷)
dst[i] = '\0';
return dst;
}| 测试场景 | 用例代码 | 预期结果 |
|---|---|---|
| 普通字符串拷贝 | char dst[20]; my_strcpy(dst, “hello world”); | dst内容为"hello world" |
| 空字符串拷贝 | char dst[10]; my_strcpy(dst, “”); | dst[0] == ‘\0’ |
| 自拷贝 | char buf[] = “test”; my_strcpy(buf, buf); | buf内容不变,仍为"test" |
| 后向内存重叠 | char buf[20] = “abcdefgh”; my_strcpy(buf+2, buf); | buf内容为"ababcdefgh"(基础版会得到"abababab…"错误结果) |
| 空参数传入 | my_strcpy(nullptr, “test”); | 返回nullptr,程序不崩溃 |
| 缓冲区不足(安全版) | char dst[5]; my_strcpy_s(dst, 5, “hello world”); | dst内容为"hell",自动截断并加结束符 |
到此这篇关于c++中strcpy()拷贝的3种写法示例详解的文章就介绍到这了,更多相关c++ strcpy()拷贝内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论