目录

  • 方法概览
    • 1. C风格字符数组的复制
      • 1.1 循环逐个字符复制
      • 1.3 使用 "memcpy" 函数
    • 2. 使用 C++ "std::string" 类
      • 2.1 使用赋值运算符 "="
      • 2.2 使用拷贝构造函数
      • 2.3 使用 "assign()" 方法
      • 选择建议
    • 注意事项

在 C++ 中,不使用 “strcpy” 函数将一个字符串复制到另一个字符串有多种方法,主要可分为使用 C 风格字符数组 和 C++ “std::string” 类 两大方向。

方法概览

方法类别 具体方法 关键特点 适用场景
C风格字符数组 循环逐个字符复制 最基础,手动管理内存和结束符 需要完全控制底层操作或受限环境
- 使用指针操作 更接近底层,可能更高效 理解指针操作,追求性能
- 使用 “memcpy” 按字节块复制,效率高 复制包括 “’\0’” 在内的整个字符串数据
C++ “std::string” 赋值运算符 “=” 最简单、安全,自动管理内存 现代C++代码的推荐方式
- 拷贝构造函数 在创建新对象时直接初始化 需要在对象构造时复制字符串
- “assign()” 方法 提供更灵活的复制选项(如子串) 需要更复杂的复制逻辑

1. C风格字符数组的复制

C风格的字符串是以空字符 ("’\0’") 结尾的字符数组。复制时需要确保目标数组有足够空间,并手动添加结束符。

1.1 循环逐个字符复制

思路:遍历源字符串的每个字符(直到遇到 “’\0’”),逐个赋值给目标数组,最后在目标数组末尾手动添加 “’\0’”。

#include <iostream>

void copyString(const char* src, char* dest) {
    int i = 0;
    // 循环复制字符,直到遇到源字符串的结束符
    while (src[i] != '\0') {
        dest[i] = src[i];
        i++;
    }
    dest[i] = '\0'; // 手动添加结束符
}

int main() {
    const char* src = "Hello, World!";
    char dest[20]; // 确保目标数组足够大

    copyString(src, dest);

    std::cout << "Copied string: " << dest << std::endl;
    return 0;
}

###cpp1.2 使用指针操作

思路:使用指针而非数组索引进行遍历和复制,原理与循环类似。

#include <iostream>

void copyString(const char* src, char* dest) {
    // 使用指针移动并复制,直到遇到源字符串的结束符
    while (*src != '\0') {
        *dest = *src;
        src++;
        dest++;
    }
    *dest = '\0'; // 手动添加结束符
}

// 更简洁的写法:
// void copyString(const char* src, char* dest) {
//    while ((*dest++ = *src++)) != '\0'); 
// }

int main() {
    const char* src = "Hello, World!";
    char dest[20]; // 确保目标数组足够大

    copyString(src, dest);

    std::cout << "Copied string: " << dest << std::endl;
    return 0;
}

1.3 使用 “memcpy” 函数

思路:计算源字符串的长度(包括结尾的 “’\0’”),然后使用 “memcpy” 按字节批量复制。这通常比逐个字符复制效率更高。

#include <iostream>
#include <cstring> // 提供 memcpy 和 strlen

int main() {
    const char* src = "Hello, World!";
    size_t length = std::strlen(src) + 1; // +1 是为了包含结束符 '\0'
    char* dest = new char[length]; // 动态分配内存

    std::memcpy(dest, src, length); // 复制字节块

    std::cout << "Copied string: " << dest << std::endl;

    delete[] dest; // 释放内存
    return 0;
}

2. 使用 C++ “std::string” 类

“std::string” 自动管理内存,无需担心缓冲区大小和结束符,是现代C++更安全、便捷的选择。

2.1 使用赋值运算符 “=”

思路:直接使用
“std::string” 的赋值运算符,这是最直观的方式。

#include <iostream>
#include <string>

int main() {
    std::string str1 = "Hello, World!";
    std::string str2;

    str2 = str1; // 使用赋值运算符

    std::cout << "Copied string: " << str2 << std::endl;
    return 0;
}

2.2 使用拷贝构造函数

思路:在定义新的
“std::string” 对象时,直接用源字符串进行初始化。

#include <iostream>
#include <string>

int main() {
    std::string str1 = "Hello, World!";
    std::string str2(str1); // 使用拷贝构造函数

    std::cout << "Copied string: " << str2 << std::endl;
    return 0;
}

2.3 使用 “assign()” 方法

思路:
“std::string” 的 “assign()” 方法提供了多种重载,可以复制整个字符串或其中一部分。

#include <iostream>
#include <string>

int main() {
    std::string str1 = "Hello, World!";
    std::string str2;

    str2.assign(str1); // 复制整个字符串

    std::cout << "Copied string: " << str2 << std::endl;
    return 0;
}

选择建议

  • 首选 “std::string”:对于现代C++开发,强烈推荐使用 “std::string”。它更安全(自动管理内存,避免缓冲区溢出)、更便捷(代码简洁),且功能强大。
  • 谨慎使用字符数组:只有在处理遗留代码、特定底层操作或特殊性能要求时,才考虑使用C风格字符数组。使用时务必仔细管理内存和结束符。

注意事项

  1. 缓冲区溢出:使用字符数组时,必须确保目标数组有足够的空间容纳源字符串(包括结尾的
    “’\0’”),否则会导致严重的程序错误或安全漏洞。

  2. 手动添加结束符:使用字符数组且自行实现复制逻辑时,切勿忘记在目标字符串末尾手动添加
    “’\0’”,否则它就不是一个有效的C字符串,后续操作(如打印)会出现未定义行为。

  3. “memcpy” 的适用性:“memcpy” 是内存块的复制,不关心内容。用于复制字符串时,需确保复制的长度包含了结尾的 “’\0’”。

希望这些方法和代码示例能帮助你更好地理解如何在C++中复制字符串。根据你的具体场景选择最合适的方法吧。

更多推荐