WEBKT

C++ 字符串与字符数组的 10 种转换方法:从入门到精通

76 0 0 0

1. std::string 转 const char* (最常用)

2. std::string 转 char* (需要谨慎)

3. const char* 转 std::string (最常用)

4. char* 转 std::string (也常用)

5. 字符数组转 std::string (利用构造函数)

6. 字符串拼接:std::string 和 const char* (简单)

7. 字符串拼接:std::string 和 char* (也简单)

8. 使用 std::stringstream 进行转换 (灵活)

9. 使用 std::copy 进行字符数组拷贝 (底层)

10. 使用 assign 方法进行字符数组赋值 (灵活)

总结

你好,我是老王。在 C++ 编程中,字符串 (string) 和字符数组 (char array) 的转换是经常遇到的问题。虽然 C++ 标准库提供了 std::string 类,简化了字符串的处理,但在某些场景下,我们仍然需要与 C 风格的字符数组交互。比如,调用 C 语言编写的 API,或者需要更底层的内存控制。所以,熟练掌握字符串和字符数组之间的转换方法,对每个 C++ 程序员来说都至关重要。

本文将详细介绍 10 种常见的转换方法,涵盖从初学者到进阶者的各种需求。我会尽量用通俗易懂的语言,结合实际的代码示例,让你能够轻松掌握这些技巧。 让我们一起开始吧!

1. std::stringconst char* (最常用)

这是最常见的转换方式。std::string 提供了 c_str()data() 两个成员函数,可以将字符串转换为 C 风格的 const char*

  • c_str(): 返回一个指向以空字符结尾的字符数组的指针。通常用于需要 C 风格字符串作为输入的情况。
  • data(): 返回一个指向字符数组的指针,不保证以空字符结尾。如果需要保证字符串以空字符结尾,请手动添加。
#include <iostream>
#include <string>
int main() {
std::string str = "Hello, world!";
// 使用 c_str()
const char* cstr1 = str.c_str();
std::cout << "cstr1: " << cstr1 << std::endl; // 输出: cstr1: Hello, world!
// 使用 data()
const char* cstr2 = str.data();
std::cout << "cstr2: " << cstr2 << std::endl; // 输出: cstr2: Hello, world!
return 0;
}

注意: c_str()data() 返回的指针指向的内存由 std::string 管理,不要试图修改该内存,也不要在 std::string 对象被销毁后使用这些指针。

2. std::stringchar* (需要谨慎)

std::string 转换为 char* 需要特别小心,因为这涉及到对字符串内容的修改。通常情况下,不推荐直接将 std::string 转换为 char*,除非你非常清楚自己在做什么。

方法一:使用 strcpymemcpy 复制字符串

这种方法创建了一个新的字符数组,并将 std::string 的内容复制到该数组中。

#include <iostream>
#include <string>
#include <cstring> // 或者 <string.h>
int main() {
std::string str = "Hello, world!";
size_t len = str.length();
// 分配足够的空间,包括空字符
char* cstr = new char[len + 1];
// 使用 strcpy
strcpy(cstr, str.c_str());
// 或者使用 memcpy
// memcpy(cstr, str.c_str(), len + 1);
std::cout << "cstr: " << cstr << std::endl; // 输出: cstr: Hello, world!
// 修改 cstr
cstr[0] = 'h';
std::cout << "cstr: " << cstr << std::endl; // 输出: cstr: hello, world!
delete[] cstr; // 释放内存
cstr = nullptr;
return 0;
}

注意:

  • 需要手动分配足够的内存。
  • 需要手动释放内存,防止内存泄漏。
  • strcpy 存在安全隐患,可能导致缓冲区溢出。建议使用 strncpymemcpy,并确保目标缓冲区足够大。

方法二:使用 &str[0] (不推荐)

std::string 内部通常使用一个 char 数组来存储字符串数据。理论上,你可以通过 &str[0] 获取指向该数组的指针。

#include <iostream>
#include <string>
int main() {
std::string str = "Hello, world!";
// 获取指向内部字符数组的指针 (不推荐)
char* cstr = &str[0];
std::cout << "cstr: " << cstr << std::endl; // 输出: cstr: Hello, world!
// 修改 cstr
cstr[0] = 'h';
std::cout << "str: " << str << std::endl; // 输出: str: hello, world!
return 0;
}

警告:

  • 这种方法依赖于 std::string 的内部实现,不保证在所有编译器或标准库版本中都有效。
  • std::string 可能会在内部重新分配内存,导致 &str[0] 指针失效。
  • 不推荐在 Release 版本中使用。

3. const char*std::string (最常用)

这是将 C 风格字符串转换为 std::string 的最简单方法。 std::string 的构造函数接受 const char* 作为参数。

#include <iostream>
#include <string>
int main() {
const char* cstr = "Hello, world!";
std::string str(cstr);
std::cout << "str: " << str << std::endl; // 输出: str: Hello, world!
return 0;
}

4. char*std::string (也常用)

const char* 类似,std::string 的构造函数也接受 char* 作为参数。

#include <iostream>
#include <string>
int main() {
char cstr[] = "Hello, world!";
std::string str(cstr);
std::cout << "str: " << str << std::endl; // 输出: str: Hello, world!
return 0;
}

5. 字符数组转 std::string (利用构造函数)

除了直接使用 char*,你还可以使用字符数组的起始地址和长度来构造 std::string

#include <iostream>
#include <string>
int main() {
char carr[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!', '\0' };
size_t len = sizeof(carr) / sizeof(carr[0]) - 1; // 减去空字符
std::string str(carr, len);
std::cout << "str: " << str << std::endl; // 输出: str: Hello, world!
return 0;
}

6. 字符串拼接:std::stringconst char* (简单)

std::string 提供了 += 运算符,可以方便地将 const char* 拼接到字符串的末尾。

#include <iostream>
#include <string>
int main() {
std::string str = "Hello";
const char* cstr = ", world!";
str += cstr;
std::cout << "str: " << str << std::endl; // 输出: str: Hello, world!
return 0;
}

7. 字符串拼接:std::stringchar* (也简单)

const char* 类似,+= 运算符也支持将 char* 拼接到字符串的末尾。

#include <iostream>
#include <string>
int main() {
std::string str = "Hello";
char cstr[] = ", world!";
str += cstr;
std::cout << "str: " << str << std::endl; // 输出: str: Hello, world!
return 0;
}

8. 使用 std::stringstream 进行转换 (灵活)

std::stringstream 是一个非常有用的工具,可以用于在字符串和各种数据类型之间进行转换。

const char*std::string:

#include <iostream>
#include <string>
#include <sstream>
int main() {
const char* cstr = "Hello, world!";
std::stringstream ss;
ss << cstr;
std::string str = ss.str();
std::cout << "str: " << str << std::endl; // 输出: str: Hello, world!
return 0;
}

char*std::string:

#include <iostream>
#include <string>
#include <sstream>
int main() {
char cstr[] = "Hello, world!";
std::stringstream ss;
ss << cstr;
std::string str = ss.str();
std::cout << "str: " << str << std::endl; // 输出: str: Hello, world!
return 0;
}

优点:

  • 可以方便地进行多种数据类型之间的转换。
  • 可以进行格式化输出。

缺点:

  • 比直接使用构造函数稍慢。

9. 使用 std::copy 进行字符数组拷贝 (底层)

std::copy 算法可以用于将字符数组的内容复制到 std::string 的内部存储中。

#include <iostream>
#include <string>
#include <algorithm> // 包含 std::copy
#include <iterator> // 包含 std::back_inserter
int main() {
char carr[] = "Hello, world!";
std::string str;
std::copy(carr, carr + strlen(carr), std::back_inserter(str));
std::cout << "str: " << str << std::endl; // 输出: str: Hello, world!
return 0;
}

说明:

  • std::back_inserter(str) 返回一个插入迭代器,它将元素添加到 str 的末尾。
  • strlen(carr) 获取字符数组的长度。

10. 使用 assign 方法进行字符数组赋值 (灵活)

std::stringassign 方法提供了更灵活的字符串赋值方式,可以从字符数组中复制指定长度的字符。

#include <iostream>
#include <string>
int main() {
char carr[] = "Hello, world!";
size_t len = strlen(carr);
std::string str;
str.assign(carr, len);
std::cout << "str: " << str << std::endl; // 输出: str: Hello, world!
return 0;
}

assign 方法的其他用法:

  • str.assign(cstr, n): 从 cstr 中复制前 n 个字符到 str
  • str.assign(n, ch): 将 str 赋值为 n 个字符 ch 的重复。

总结

掌握 C++ 字符串和字符数组之间的转换方法,可以让你更灵活地处理字符串,并与 C 语言库进行交互。 我总结了 10 种常用的转换方法,希望能帮助你解决实际开发中的问题。

  • std::stringconst char*: 使用 c_str()data()
  • std::stringchar*: 谨慎使用,推荐使用 strcpymemcpy 复制字符串,并手动管理内存。
  • const char*std::string: 使用构造函数。
  • char*std::string: 使用构造函数。
  • 字符数组转 std::string: 使用构造函数,指定起始地址和长度。
  • 字符串拼接: 使用 += 运算符。
  • 使用 std::stringstream 进行转换: 灵活,可以进行多种数据类型转换。
  • 使用 std::copy 进行字符数组拷贝: 底层,需要使用插入迭代器。
  • 使用 assign 方法进行字符数组赋值: 灵活,可以指定复制的字符数量。

希望这篇文章对你有所帮助。如果你有任何问题或建议,欢迎在评论区留言。 祝你编程愉快!

老王侃码 C++字符串字符数组

评论点评

打赏赞助
sponsor

感谢您的支持让我们更好的前行

分享

QRcode

https://www.webkt.com/article/7559