std::string
实际上可以容纳'\0'
字符的事实一直存在。这当然与C风格的字符串不一致。
所以我想知道,这是设计,还是遗漏,或者只是标准不禁止它,编译器允许这种情况发生?
答案 0 :(得分:12)
我想知道你的争吵是什么。 '\0'
只是另一个角色。没有有效的方法可以在通用的“char”字符串中禁止它。
同一个角色在C中具有特殊含义是不幸的,但必须在遗留代码与其互操作时立即处理为每个限制。
只要您坚持使用std::string
专有的代码,这不应该是个问题。
要解决您的评论,我们需要查看在{32}中char*
basic_string(const charT* s, const Allocator& a = Allocator())
21.4.2 9/10
的构造函数。它表示内部字符串的大小是通过traits::length(s)
确定的,在std::string
的情况下strlen
是std::string
,它要求其参数为空终止。所以,是的,如果您尝试从const char*
构造{{1}},则需要将其终止。
答案 1 :(得分:3)
有一组函数接受'char *'参数并假设字符串以零结尾。如果你仔细使用它们,你当然可以使用0的字符串。
相比之下,STL字符串故意允许零字节,因为它们不使用0作为终止。因此,对你的问题的简单回答是,'是的,按设计。'答案 2 :(得分:1)
标准并未说明在std :: string '\0'
的情况下是任何特殊字符。因此,std::string
的任何合规实现都不应将'\0'
视为任何特殊字符。当然,除非将const char*
传递给字符串的成员函数,该函数假定为以null结尾。
答案 3 :(得分:1)
按设计。
C也可以没有以空字符结尾的字符串:
char sFoo[4];
strncpy(sFoo,"Test",sizeof(sFoo));
其中sFoo
包含非NULL终止字符串。
它有Null-Terminated字符串,可以像0一样
struct String {
char *str;
size_t length;
size_t capacity;
};
字符串文字是NUL终止的,但这并不总是指字符串。
因此,让NUL终止字符串是练习,但它确实意味着0表示无效字符。
答案 4 :(得分:0)
strncpy
与strncat
那就是说,如果有空间,strncpy和strncat等会附加一个空终止符。
实际上strncpy
和strncat
非常不同:
strncpy
将“NUL填充的n字节字符串”写入 n 字节缓冲区:长度 l 的字符串大多数 n ,这样最后的 n - l 字节用NUL填充。注意复数:所有最后的字节都归零,只记下一个。另请注意, l 的最大允许值实际上是 n ,因此NUL字节可能为零:缓冲区可能无法保存以NUL结尾的字符串。 (GCC有一个非便携函数来测量这种“NUL填充的n字节字符串”:strnlen
。)
相反,strncat
将NUL终止的字符串输出到缓冲区。在这两种情况下,如果字符串太长,则字符串会被截断,但在strncpy
的情况下, n 字母字符串将适合 n 字节缓冲区,而在strncat
的情况下, n 字母的结果只适合( n +1) - 字节缓冲区。
这种差异会给C初学者甚至非初学者带来很多困惑。我甚至看过教授“安全C编程”的课程和书籍,这些编程混淆了与这些标准函数相关的信息。
这些所谓的“安全”C字符串操作函数(“strn*
”系列)在C“安全编程”社区中受到了极大的批评,并且更好的设计(但非标准)替代品发明了(特别是“strl*
”家族:strlcpy
...)。
要点:
strncpy
会附加一个空终结符如果有空间; strncat
将附加空终结符始终。