C++ 答案是:“;字符串可以容纳'\0';“字符”;是故意的吗?
C++ 答案是:“;字符串可以容纳'\0';“字符”;是故意的吗?,c++,standards,C++,Standards,std::string实际上可以容纳'\0'字符这一事实一直存在。这当然与C风格的字符串不一致 所以我想知道,这是出于设计,还是遗漏,还是仅仅因为标准没有禁止它,编译器允许这种情况发生?标准没有说在std::string的情况下,'\0'是任何特殊字符。因此,std::string的任何兼容实现都不应将'\0'视为任何特殊字符。当然,除非const char*被传递给字符串的成员函数,该函数被假定为以null结尾。有一组函数接受“char*”参数,并假定字符串以零结尾。如果仔细使用它们,肯定会有
std::string
实际上可以容纳'\0'
字符这一事实一直存在。这当然与C风格的字符串不一致
所以我想知道,这是出于设计,还是遗漏,还是仅仅因为标准没有禁止它,编译器允许这种情况发生?标准没有说在std::string的情况下,
'\0'
是任何特殊字符。因此,std::string
的任何兼容实现都不应将'\0'
视为任何特殊字符。当然,除非const char*
被传递给字符串的成员函数,该函数被假定为以null结尾。有一组函数接受“char*”参数,并假定字符串以零结尾。如果仔细使用它们,肯定会有0的字符串
相反,STL字符串故意允许零字节,因为它们不使用0来终止。所以你的问题的简单答案是,‘是的,是有意的’我想知道你的争吵是什么<代码>“\0”只是另一个字符。在通用“char”字符串中,没有有效的方法禁止它。 不幸的是,同一个字符在C语言中有特殊的含义,但一旦您与遗留代码进行交互操作,就必须将其作为遗留代码施加的每个限制来处理 只要您坚持只使用
std::string
的代码,这就不应该成为问题
为了回应您的评论,我们需要查看在n3242中采用21.4.2 9/10
的basic_字符串(const charT*s,const Allocator&a=Allocator())的构造函数。它表示内部字符串的大小是通过traits::length(s)
确定的,在std::string
的情况下,它是strlen
,要求其参数以null结尾。因此,是的,如果您试图从常量char*
构造std::string
,它需要以空结尾。设计
C也可以有不以null结尾的字符串:
char sFoo[4];
strncpy(sFoo,"Test",sizeof(sFoo));
其中,sFoo
保存以非空结尾的字符串
它有以Null结尾的字符串,可以有0
struct String {
char *str;
size_t length;
size_t capacity;
};
字符串文字以NUL结尾,但并不总是引用字符串
因此,以NUL结尾的字符串是一种实践,但它确实意味着0是无效字符。strncpy
vs.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
char*
可以指向包含空字节的缓冲区,但该缓冲区不能称为C字符串。我认为C样式的字符串与“字符串”不一致\“0”是一个有效字符,使用它作为终止符会导致元素数组的奇异行为,其中256的集合中的一个特定值被排除。就我个人而言,我认为使用空终止符是99.9%的U**x“应用程序”使用基于文本的解释性bash脚本的原因。如果字符串在data@Martin:right on中提前被空终止,开发人员害怕使用编译代码。不允许一些随意的角色是一种怪癖,而不是相反。我想我没有正确地表达这一点。我想我要问的是std::string
是否与终止的字符串一起工作(不必以NUL结尾),或者根本不关心。此外,函数c_str()
生成一个以null结尾的字符串,其中null是任何字符类型的值初始化的结果。@Potatoswatter是整个以null结尾的字符串的抽象。从来没有这样想过。请看C,其他人也这么想:)也就是说,strncpy
和strncat
等如果有空间,将附加一个空终止符。@KerrekSB这些函数是不同的。看看我的答案。