是:“std :: string可以设计'\ 0'字符”吗?

时间:2011-09-14 12:45:35

标签: c++ standards

std::string实际上可以容纳'\0'字符的事实一直存在。这当然与C风格的字符串不一致。

所以我想知道,这是设计,还是遗漏,或者只是标准不禁止它,编译器允许这种情况发生?

5 个答案:

答案 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的情况下strlenstd::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)

strncpystrncat

  

那就是说,如果有空间,strncpy和strncat等会附加一个空终止符。

实际上strncpystrncat非常不同:

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将附加空终结符始终