std::string
实际上可以容纳 '\0'
字符,这一点经常被提及。当然,这与 C 风格的字符串不一致。
所以我想知道,这是故意的设计,还是疏漏,或者只是标准没有禁止而编译器允许出现这种情况?
std::string
实际上可以容纳 '\0'
字符,这一点经常被提及。当然,这与 C 风格的字符串不一致。
所以我想知道,这是故意的设计,还是疏漏,或者只是标准没有禁止而编译器允许出现这种情况?
我想知道你们争论的是什么。 '\0'
只是另一个字符,没有有效的方式来禁止它出现在一般用途的 'char' 字符串中。
虽然相同的字符在 C 语言中有特殊含义,但只要你与它进行交互,就像是遇到遗留代码带来的每一个限制一样,必须处理它。
只要坚持使用仅使用 std::string
的代码,这不应该成为问题。
为了解决您的评论,我们需要查看使用 char*
的构造函数,这将在 n3242 中的 21.4.2 9/10
中表示为 basic_string(const charT* s, const Allocator& a = Allocator())
。它指出内部字符串的大小是通过 traits::length(s)
确定的,在 std::string
的情况下,该函数是 strlen
,它要求其参数是以 null 结尾的。因此,如果您尝试从 const char*
构造一个 std::string
,则需要以 null 结尾。
std::string
是否适用于终止字符串(不一定是以 NUL 结尾),或者根本不关心。 - Šimon Tóthc_str()
生成一个以空字符结尾的字符串,其中空字符是字符类型的值初始化的结果。 - Potatoswatter有一组函数接受'char *'参数并假定字符串以零结束。如果你小心使用它们,你可以确保字符串中有0。
相比之下,STL字符串有意允许零字节,因为它们不使用0作为终止符。所以简单地回答你的问题是,“是的,这是设计上的特点。”
char*
指针可以指向包括空字节的缓冲区,但这个缓冲区不能被称为 C 字符串。 - Magnus Hoff按设计而来。
C语言也可以有非空终止字符串:
char sFoo[4];
strncpy(sFoo,"Test",sizeof(sFoo));
sFoo
保存的是非NULL结尾的字符串。
它也可以有以Null结尾的字符串,这些字符串可能为0。
struct String {
char *str;
size_t length;
size_t capacity;
};
字符串字面量以NUL结尾,但这并不总是指字符串。
因此,拥有以NUL结尾的字符串是一种惯例,但这并不意味着0是无效字符。
strncpy
和strncat
等函数如果有足够的空间,仍然会添加一个空终止符。 - Kerrek SBstrncpy
vs. strncat
话虽如此,如果有空间,
strncpy
和strncat
等函数会追加一个空终止符。
实际上,strncpy
和strncat
是非常不同的:
strncpy
将一个“NUL填充的n字节字符串”写入一个n字节缓冲区:一个长度为l的字符串,其中l最大为n,因此最后的n-l个字节都被填充为NUL。请注意复数形式:所有最后的字节都被清零,而不仅仅是一个。还要注意的是,l的最大允许值确实是n,因此可能没有NUL字节:缓冲区可能不包含以NUL结尾的字符串。(GCC有一个非便携式函数来测量这样的“NUL填充的n字节字符串”:strnlen
。)
strncat
将一个以 NUL 结尾的字符串输出到缓冲区中。在两种情况下,如果字符串过长,都会被截断,但是在 strncpy
的情况下,一个长度为 n 的字符串将适合于一个 n 字节的缓冲区,而在 strncat
的情况下,一个长度为 n 的结果只能适合于(n+1) 字节的缓冲区。strn*
”族)在 C “安全编程”界面临着很多批评,并已经发明了更好的设计(但非标准的)替代品(尤其是“strl*
”族: strlcpy
…)。strncpy
只有在有空间的情况下才会附加一个空终止符;strncat
总是会附加一个空终止符。