如何使std::string与char*兼容?

6

我通常会发现一些将char*作为其参数的函数。但是我听说在C++中推荐使用std::string。怎样才能够将一个std::string对象用于需要char*作为参数的函数中呢?目前,我已经知道了c_str()函数,但是它不能够在需要修改字符串内容时使用。

3个回答

6

为此,您可以使用 std::string::data()。返回指向内部数据的指针。请注意不要释放此内存或类似行为,因为该内存由字符串对象管理。


1
@idclev463035818 有些人说,如果你读取空终止符后面的内容,你就能找到每一个互联网页面。 :) - Evg
非常感谢! - noob_in_math
至少可以肯定的是,没有人会说你在那里找不到它们。 - François Andrieux
1
@Evg不要嘲笑我,我看过互联网,没有任何附加条件 :P - 463035818_is_not_a_number

6
你可以像这样使用 C++11 后的第一个元素的地址:
void some_c_function(char* s, int n);

// ...

std::string s = "some text";

some_c_function(&s[0], s.size());

C++11之前,内部字符串存储在连续缓冲区中或者它是否以空字符结尾都没有保证。在这些情况下,复制字符串是唯一安全的选择。

C++17(当前标准)之后,您可以使用以下代码:

some_c_function(s.data(), s.size());

在C++17中,除了const版本外,还添加了std::string::data()的非const返回值。

据推测,some_c_function将在“缓冲区”中留下一个以'\0'结尾的C风格字符串。之后需要调整字符串大小,因为其大小包括'\0'和其余尾随空闲“缓冲区”。 - Eljay
@Eljay 可能是这样。但我不想猜测 C 函数可能会做什么。一些遗留函数不修改字符串,只是在使用const时比较宽松。此外,许多函数只是填充字符串缓冲区并返回已填充的长度。可能存在替代结束值(例如 \n)等... - Galik
C++11之前有什么不同? - 463035818_is_not_a_number
好的,说得对。我可以想到几种不同的缓冲区使用方式。它可能被用作二进制缓冲区,所以 '\0' 可能只是数据(仅用于输入、输入/输出或仅输出缓冲区)。它可能只是一个 C 风格的字符串输入(因此大小应该无关紧要)。它可能是一个 C 风格的字符串输出缓冲区,因此大小作为缓冲区限制以防止溢出非常重要。这完全取决于 API。 - Eljay
在C++11之前,没有保证内部字符串存储在连续的缓冲区中或者它是否以空字符结尾。但是实际上,大多数实现都是这样的,因为这使得c_str()的实现变得简单。因此,当C++11更改要求需要连续性和空终止时,大多数实现已经符合规定(这可能是C++11首先进行更改的原因之一,即使常见做法标准化)。 - Remy Lebeau

4
自 C++17 起,std::string::data() 返回指向底层 char 数组的指针,允许修改字符串内容。然而,与字符串一般情况相同,您不能写入超出其结尾的内容。从cppreference得知:
“将存储在`data()+size()`处的过去结束的空字符修改为除`CharT()`之外的任何值都具有未定义行为。”

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接