wstring是否以空字符结尾?

9

std::wstring的内部结构是什么?它包含长度吗?它是以null结尾的吗?还是两者都有?


http://www.cplusplus.com/forum/general/46247/ - Krishnabhadra
3个回答

14

它包括长度吗?

是的。这是C++11标准所必需的。

§ 21.4.4

size_type size() const noexcept;
1. 返回: 当前字符串中类似字符的数量计数。
2. 复杂度: 常数时间。

请注意,此操作不考虑Unicode编码。


它是以null结尾的吗?

是的。C++11标准还要求std::basic_string::c_str在范围[0,size()]内返回有效指针,其中my_string[my_string.size()]将有效,因此需要一个空字符。

§ 21.4.7.1

const charT* c_str() const noexcept;
const charT* data() const noexcept;
1. 返回: 指针p,使得对于[0,size()]中的每个ip + i == &operator[](i)
2. 复杂度: 常数时间。
3. 要求: 程序不得更改字符数组中存储的任何值。


2
@JonathanAllen 我不会从标准中学习,因为它充满了标准术语,很难阅读。然而,你可以在这里找到C++14 CD(http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3690.pdf),以及多个草案和标准化过程。 - Rapptz
1
我不知道你在将它与什么进行比较,但是你刚刚发布的内容比MSDN上的文档容易理解得多。 - Jonathan Allen
2
如果你想要一份好的易读文档,我绝对支持这个:http://en.cppreference.com/w/Main_Page - Rapptz
1
对于快速参考来说还不错,但是当第一次学习某个东西时,我更喜欢阅读一本书。特别是那些涵盖所有细节的书籍。 - Jonathan Allen
标准并不要求将长度存储为字段。例如,如果您只存储了wchar_t头和尾指针并取其差,您可以在不必存储长度的情况下以恒定时间获取长度。 - SheetJS
显示剩余9条评论

11

我们不知道,这完全取决于实现。 (至少到 C++03 - 显然 C++11 要求内部缓冲区为 0 结尾。) 如果你使用的开源库,你可以查看 C++ 标准库实现的源代码。


除此之外,如果它以 NUL 结尾并且存储了一个显式长度,那么我认为这是合乎逻辑的。这样做很好,因为它可以在常数时间内返回长度和有效的 C 字符串:
size_t length()
{
    return m_length;
}

const wchar_t *c_str()
{
    return m_cstr;
}

如果它没有存储显式长度,那么size()将不得不计算字符直到NUL为止,这是一种浪费,如果可以避免的话。
然而,如果内部缓冲区没有以NUL结尾,但仅存储了长度,则创建适当的以NUL结尾的C字符串将是繁琐的:字符串必须重新分配其存储并附加0(重新分配是昂贵的操作),或者它必须复制整个缓冲区,这又是一个O(n)操作。
(警告:无耻的自我推销-在我目前正在进行的C语言项目中,我采用了这种方法来实现灵活的字符串对象。)

4
在C++11中,保证std::string是以空字符结尾的。 - Jesse Good

0

basic_string(其中wstring是typedef)不需要终止符。

是的,它管理自己的长度。

如果您需要一个以null结尾(也称为C字符串)的string/wstring版本,请调用c_str()。但是它可以在内部包含空字符,在这种情况下,几乎每个处理C字符串的C函数都将无法查看整个字符串。


1
很抱歉,这并没有回答问题。OP正在询问字符串的内部实现,他很可能非常清楚.c_str()成员函数的使用方法和原因。此外,我希望您了解C标准库中的宽字符串处理函数,例如wstrlen() - user529758
实际上,我是一名记者,试图撰写有关Platform::StringReference如何与wchar_t和wstring配合使用的文章。显然,StringReference“需要一个以null结尾的字符串类型(wchar_t或wstring)”,才能在不创建副本的情况下正常工作。或者他的意思是“需要一个(以null结尾的字符串类型wchar_t*)或wstring”。可惜口头语言没有括号。 - Jonathan Allen
1
是的,我完全没有回答他的问题,被选中的答案在一小时后给出了与我完全相同的三个答案。也许我应该写一篇长篇散文而不是回答问题,或者只是引用标准但误解它。 - DanielKO

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