C++ std::带和不带\0终止符的字符串
假设我创建了如下字符串:C++ std::带和不带\0终止符的字符串,c++,C++,假设我创建了如下字符串: std::string s1 = ""; s1 += 'a'; s1 += 'b'; std::string s2 = std::string( "ab" ); 然后是这样一个: std::string s1 = ""; s1 += 'a'; s1 += 'b'; std::string s2 = std::string( "ab" ); s1和s2是否相等?创建s2时,\0是否从“ab”中剥离?如果没有,是否有一种简单(最好是一行)的方法来检查s1是否只包含且
std::string s1 = "";
s1 += 'a';
s1 += 'b';
std::string s2 = std::string( "ab" );
然后是这样一个:
std::string s1 = "";
s1 += 'a';
s1 += 'b';
std::string s2 = std::string( "ab" );
s1
和s2
是否相等?创建s2
时,\0
是否从“ab”
中剥离?如果没有,是否有一种简单(最好是一行)的方法来检查s1
是否只包含且准确地{'a','b'}
s1和s2相等吗
对
创建s2时\0是否从“ab”中剥离
这不是一个真正有意义的问题。构造s2
的代码可以根据需要进行构造。它可以复制终结者,移除它,留下它,不管它想要什么。它只需要知道如何找到C样式字符串的结尾,它确实知道
如果没有,是否有一种简单(最好是一行)的方法来检查s1是否只包含并且准确地包含{'a','b'}
string
类有一个操作符==
,它执行您可能期望的操作,比较等价值。它了解C样式和C++样式字符串的工作方式,因此可以比较它们的值。使用方法size()可以很容易地确定发生了什么
例如,在创建这样的对象之后
std::string s1 = "";
std::string s1( s );
s1的大小将等于0
这里称为构造函数
basic_string(const charT* s, const Allocator& a = Allocator());
basic_string(const charT* s, size_type n, const Allocator& a = Allocator());
从数组中复制字符,数组的第一个元素由s指向。由于字符串文字“”的长度等于0,因此构造的对象也没有元素,其大小等于0
在这些声明之后
s1 += 'a';
s1 += 'b';
对象将包含两个字符“a”和“b”。
因此,对象将等于像std::string(“ab”)这样构造的对象代码>
例如,如果有一个字符数组定义为
字符s[]={a',b','\0',c',d','\0'}
并将用于构造std::string类型的对象,如下所示
std::string s1 = "";
std::string s1( s );
那么s1将只包含两个元素“a”和“b”,其大小将等于2
考虑另一个例子是有用的。假设你写了
std::string s1 = "";
然后
s1 += 'a';
s1 += 'b';
s1 += '\0';
在这种情况下,s1将不等于objectstd::string(“ab”)
,因为s1的大小现在等于3
另一个有趣的例子。您可以使用构造函数
basic_string(const charT* s, const Allocator& a = Allocator());
basic_string(const charT* s, size_type n, const Allocator& a = Allocator());
它与前面的构造函数类似,只是它允许显式指定指针s指向的字符数组中的字符数,这些字符将用于构造std::string类型的对象。
在这种情况下,如果你愿意写
std::string s1( "ab", 3 );
std::cout << s1.size() << std::endl;
if ( s1 == std::string( "ab" ) ) std::cout << "They are equal" << std::endl;
else std::cout << "They are not equal" << std::endl;
std::cout << s1 << std::endl;
同时如果你愿意写
std::string s1( "ab", 3 );
std::cout << s1.size() << std::endl;
if ( s1 == std::string( "ab" ) ) std::cout << "They are equal" << std::endl;
else std::cout << "They are not equal" << std::endl;
std::cout << s1 << std::endl;
如果您想知道s1
和s2
是否相等,您可以自己检查:bool are_equal=s1==s2代码>@jalf我不确定说“字符串不包含空字节”是否有意义。它的值不是,但对于C样式的字符串也是如此(可以说)。重要的是,这并不重要——C++风格的字符串是如何终止或存储它们的长度是未指定的和无关的。StackOverflow的共识似乎是,在C++11std::string
s中,由于对C_str
@DavidSchwartz的要求,s确实是空终止的,但是std::string
不能如果\0
没有意义,则null终止,对吗?否则,将\0
插入到字符串的中间会使它变短。@cyangekko它可以nul终止,因为它的末尾可以有一个零字节。它不能以null结尾,因为您可以通过扫描nul来确定它的“真正端点”。C样式字符串也是如此--const char*j=“a\0b;”
。您可以将其视为以nul结尾的三字节字符串,但当然不能通过扫描nul来确定其真正长度。@DevSolar它不是。我很清楚这一区别,这就是我明确提到C++11的原因。在C++98/03中,标准没有确保这一点,因为IIRCC_str
被允许复制周围的数据。例如,检查。