c_str()获取只读c字符串指针,适用于传给fopen等不修改内容的c函数;需可写副本时用vector或copy()手动拷贝并补'\0'。

用 c_str() 获取只读的 C 风格字符串指针
绝大多数时候,你并不需要真正“复制”一个 char 数组,只是想把 std::string 传给 C 函数(比如 fopen、printf、strlen),这时直接用 c_str() 就行:
std::string s = "hello"; const char* p = s.c_str(); // 安全,只读,以 '\0' 结尾
注意:c_str() 返回的是 const char*,不能修改内容;且指针有效期只到下一次该 string 的非 const 成员函数被调用(比如 push_back、clear)或对象析构为止。
用 copy() 手动拷贝到已有 char 数组
如果你确实需要一份可写的、独立的 char 数组(比如要传给会修改它的 C API),得自己分配空间并拷贝:
std::string s = "world"; char buf[100]; s.copy(buf, s.size()); // 拷贝 s.size() 个字符,不带 '\0' buf[s.size()] = '\0'; // 必须手动补 '\0'
常见错误:
- 忘记补
'\0',导致后续当 C 字符串用时越界读取 - 目标数组太小,
copy()不检查边界,直接越界写 —— 用min(s.size(), sizeof(buf)-1)更安全 - 误用
data():C++11 起data()和c_str()行为一致(都保证末尾有'\0'),但 C++11 之前data()不保证结尾是'\0'
用 std::vector<char></char> 动态构造可写副本
避免栈缓冲区大小硬编码,也规避手动管理 '<p>避免栈缓冲区大小硬编码,也规避手动管理 <code>'\0' 的麻烦:
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
std::string s = "test";
std::vector<char> v(s.begin(), s.end());
v.push_back('\0'); // 确保结尾有 '\0'
char* cstr = v.data(); // 可写,生命周期由 vector 控制</char>
适用场景:
- 需要传给会修改内容的 C 函数(如
strtok、某些解析库) - 不确定字符串长度,又不想用
new[]/delete[] - 配合 RAII 管理内存,比裸指针更安全
别用 &s[0] 直接取地址(除非你清楚后果)
&s[0] 在 C++11 后能拿到可写的首字符地址,但它不保证后面有 '\0',也不代表整个 C 字符串有效:
std::string s = "abc"; char* p = &s[0]; // p 指向 'a',但 p+3 处不一定是 '\0'
所以它只适合传给明确接受“字符指针 + 长度”的函数(如 write()、send()),不能当普通 C 字符串用。误用会导致未定义行为,比如传给 printf("%s", p) 就可能崩。
真正需要可写且以 '\0' 结尾的 C 字符串时,vector<char></char> 是最不容易出错的选择;硬要上栈数组,就老老实实 copy() + 补 '\0',别图省事跳过这一步。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










