C++ string怎么转char数组 C++ strcpy与strncpy安全复制方法【转换】

8次阅读

c_str() 返回以结尾的只读C字符串指针,data()在c++17前不保证结尾有;二者均不可写,需显式分配内存并确保足够空间(≥长度+1)后复制,必要时手动补。

C++ string怎么转char数组 C++ strcpy与strncpy安全复制方法【转换】

String.c_str() 和 string.data() 的区别与选择

直接用 string.c_str() 获取 C 风格字符串指针是最常见做法,但它返回的是 const char*,不能用于写入;若你确实需要可修改的 char 数组(比如传给老式 C API 做输入输出),必须自己分配内存并复制内容。string.data() 在 C++11 中也返回 const char*(C++17 起才保证结尾有 ''),所以它和 c_str() 此时行为一致,**不能替代 strcpy 目标缓冲区**。

常见错误是这样写:

std::string s = "hello"; char* buf = const_cast(s.c_str()); // 危险!底层内存不可写 strcpy(buf, "world"); // 未定义行为

  • 要写入,必须用 new char[n+1]数组(如 char buf[256])显式分配空间
  • 目标缓冲区大小必须 ≥ s.Length() + 1,否则复制会越界
  • 复制后记得手动加 ''(如果用 strncpy 且源长度 ≥ 缓冲区长度)

strcpy 复制 string 到 char 数组的正确步骤

strcpy 本身不检查目标空间大小,依赖程序员确保目标足够大。从 std::string 复制时,必须先确认容量再调用:

std::string s = "test"; char buf[32]; if (s.length() < sizeof(buf)) {     strcpy(buf, s.c_str()); } else {     // 处理截断或报错 }
  • 永远不要对未知长度的 string 直接调用 strcpy(buf, s.c_str())
  • sizeof(buf) 只对数组名有效,对指针(如 char* buf = new char[32])无效
  • 若目标是分配内存,记得 delete[] buf,避免泄漏

strncpy 更安全?但要注意三个陷阱

strncpy 看似安全,实则容易埋坑:它不保证目标以 '' 结尾,也不自动补满整个缓冲区,还可能掩盖越界问题。

std::string s = "hello world"; char buf[5]; strncpy(buf, s.c_str(), sizeof(buf)-1); buf[sizeof(buf)-1] = ''; // 必须手动补 ''
  • 参数三(最大拷贝数)应为 sizeof(buf) - 1,留一位给 ''
  • 如果 s.length() >= sizeof(buf)strncpy 不会写 '' —— 必须手动补
  • 如果 s.length() ,strncpy 会用 '' 填满剩余位置,浪费性能
  • 现代 C++ 更推荐 std::copy_n + 手动置 '',或直接用 std::vector

更现代、更少出错的替代方案

绕过 C 风格函数,用标准库能避开大多数缓冲区问题:

立即学习C++免费学习笔记(深入)”;

  • 需要临时 C 字符串只读?直接传 s.c_str(),无需复制
  • 需要可修改副本且长度已知?用 std::vector v(s.begin(), s.end()); v.push_back('');
  • 需要固定大小缓冲区?用 std::Array buf{}; std::copy_n(s.begin(), std::min(s.size(), buf.size()-1), buf.begin()); buf.back() = '';
  • 对接旧 API 必须传 char*?优先封装成 RaiI 类管理生命周期,而不是裸指针 + strcpy

真正麻烦的从来不是“怎么转”,而是“谁负责释放”“是否会被改写”“下次读取前有没有被覆盖”——这些逻辑比一行 strcpy 重得多。

text=ZqhQzanResources