c++oding="utf-8" ?>
应使用c_str()获取只读const char*指针,安全高效;需可写时须拷贝至vector或手动分配缓冲区并补'\0',禁止const_cast修改或依赖&s[0]。
![c++ string怎么转换成字符数组char[]](https://img.php.cn/upload/article/001/221/864/179031931774722.png?x-oss-process=image/resize,p_40)
用 c_str() 获取只读的 C 风格字符串指针
绝大多数场景下,你并不需要真正“复制”成可修改的 char[],只需要一个以 \0 结尾的只读字符序列 —— 这正是 std::string::c_str() 的用途。它返回 const char*,指向内部缓冲区,安全、零拷贝、高效。
常见错误是试图把 c_str() 强转成 char* 去修改内容,这会导致未定义行为(比如程序崩溃或静默数据损坏):
std::string s = "hello"; char* p = const_cast<char>(s.c_str()); // 危险!不要这么做 p[0] = 'H'; // 未定义行为</char>
- 适用于
fopen、printf、strlen等 C 函数入参 - 返回指针在
string被修改或析构后立即失效 - 不能用于需要写入的 API(如
getcwd、某些 Win32 函数)
用 copy() + 手动补 \0 构造可写的 char[]
当你明确需要一块可修改、独立于原 string 生命周期的字符数组时,得自己分配空间并拷贝。注意:copy() 不自动加结尾 <p>当你明确需要一块可修改、独立于原 <code>string 生命周期的字符数组时,得自己分配空间并拷贝。注意:copy() 不自动加结尾 \0,漏掉这一步会导致后续使用时读越界。
正确做法:
std::string s = "hello"; char buf[6]; // 长度 = s.length() + 1 s.copy(buf, s.length()); // 拷贝前 5 个字符 buf[s.length()] = '\0'; // 必须手动补 '\0'
- 目标数组大小必须 ≥
s.length() + 1,否则copy()抛std::out_of_range -
copy(dest, n)最多拷贝n字节,不会写超出dest边界 —— 安全但不自动补\0 - 如果不确定长度,优先用
std::vector<char></char>动态分配:std::vector<char> buf(s.begin(), s.end()); buf.push_back('\0');</char>
用 data() 在 C++11 后的特殊场景
C++11 起,std::string::data() 行为和 c_str() 一致(都返回以 \0 结尾的 const char*),但 C++17 开始它也允许返回非空终止的指针(实际编译器基本仍保证 \0 存在)。除非你在对接要求非空终止的极少数底层接口,否则别依赖 data() 的可写性。
-
data()和c_str()在当前主流标准库(libstdc++、libc++、MSVC STL)中完全等价 - 永远不要对
data()返回值做const_cast后写入 - 若需可写缓冲区,还是走
copy()或std::vector<char></char>
避免用 &s[0] 替代可写数组
有人会写 &s[0] 拿到首地址,误以为能当可写 char[] 用。这在 C++11 前不安全(string 不保证连续存储),C++11 起虽强制连续,但仍有严重隐患:
-
s[0]对空字符串s是未定义行为(s.length() == 0时不能索引) - 即使非空,该指针在
string重新分配内存时(如 push_back 触发扩容)立即失效 - 无法保证后面有足够空间容纳额外字符或
\0
真正需要可写缓冲区时,宁可多写两行用 std::vector<char></char>,也别赌 &s[0] 的稳定性。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











