假设我们有一个字符串
std::string str; // some value is assigned
str.empty()和str[0] == '\0'有什么区别?
如果字符串为空,则string_variable[0]
要求返回空字符。这样就不会产生未定义的行为,如果字符串确实为空,则比较仍然有效。但是,您可能有一个以空字符开头的字符串("\0Hi there"
),即使它不为空,它也会返回true
。如果您真的想知道它是否为空,请使用empty()
。
区别在于,如果字符串是空的,则string_variable[0]
具有未定义的行为;除非该字符串是const
限定的,否则不存在索引0。如果该字符串被const
修饰,那么它将返回一个空字符。
string_variable.empty()
则在字符串为空时返回true,在不为空时返回false。这种行为不会产生未定义的结果。
empty()
用于检查字符串/容器是否为空。它适用于所有提供该函数的容器,并且使用empty
可以清楚地表明您的意图-这对于阅读代码(包括您自己)的人来说很重要。
empty()
也能在不需要改变代码的情况下与 std::u16string
一起使用。 - Panagiotis Kanavosstring.size() == 0
时,string[0]
是合法的吗?这听起来非常不像 C++。 - David Haimstr[str.size()] == '\0'
,也就是说,如果一个字符串为空,则 str[0] == '\0'
。但是,C++字符串具有显式长度字段,这意味着它可以包含嵌入的空字符。std::string str("\0ab", 3)
,str[0] == '\0'
,但是str.empty()
为false。str.empty()
比 str[0] == '\0'
更易读。std::string
并不需要以 null 结尾。至少不是每一个 null 都是其终止符。 - anon这里的其他答案都是100%正确的。我只想再添加三点说明:
empty
是通用的(每个STL容器都实现了此函数),而operator []
与size_t
仅适用于字符串对象和类似数组的容器。在处理通用STL代码时,应优先选用empty
。
而且,empty
相当明确易懂,而=='\0'
则不然。
当你在凌晨2点调试代码时,你更喜欢看到if(str.empty())
还是if(str[0] == '\0')
?
如果只考虑功能,我们都将使用纯汇编语言来编写。
此外,还涉及性能损失问题。empty
通常通过将字符串的大小成员与零进行比较来实现,这非常便宜、易于内联等。而对比第一个字符可能会更消耗资源。首先,由于所有字符串都实现了短字符串优化,程序必须首先询问字符串处于“短模式”还是“长模式”。分支-性能更差。如果字符串很长,解引用它可能是昂贵的,特别是如果该字符串已被“忽略”一段时间且解引用本身可能会导致缓存故障,这也是代价高昂的。
\0
/空的NULL结尾字符串而不是空字符串对象(是的,不太可能但有可能),那么if(str[0] == '\0')
是完全有效的。 - Peter Schneiderempty()方法并不是通过查找位置0处是否存在空字符来实现的,它只是
bool empty() const
{
return size() == 0 ;
}
这可能是不同的情况
另外,如果您使用C++ 11或更高版本,请注意您要使用的函数:
#include <iostream>
#include <cstring>
int main() {
std::string str("\0ab", 3);
std::cout << "The size of str is " << str.size() << " bytes.\n";
std::cout << "The size of str is " << str.length() << " long.\n";
std::cout << "The size of str is " << std::strlen(str.c_str()) << " long.\n";
return 0;
}
将返回
str的大小为3个字节。
str的大小为3个长整型。
str的大小为0个长整型。
str.empty()
和 str[0] == '\0'
的区别。让我们看一个例子:#include<iostream>
#include<string>
using namespace std;
int main(){
string str, str2; //both string is empty
str2 = "values"; //assigning a value to 'str2' string
str2[0] = '\0'; //assigning '\0' to str2[0], to make sure i have '\0' at 0 index
if(str.empty()) cout << "str is empty" << endl;
else cout << "str contains: " << str << endl;
if(str2.empty()) cout << "str2 is empty" << endl;
else cout << "str2 contains: " << str2 << endl;
return 0;
}
输出:
str is empty
str2 contains: alues
str.empty()
可以告诉你字符串是否为空,str[0] == '\0'
可以告诉您字符串的0索引是否包含'\0'
。 你的字符串变量0索引包含'\0'
并不意味着你的字符串是空的。 是的,仅当您的字符串长度为1且您的字符串变量0索引包含'\0'
时才有可能出现这种情况。那时你可以说它是一个空字符串。
C++中的字符串有空或非空的概念。如果字符串为空,则str [0]未定义。只有当C ++字符串大小> 1时,str [0]才被定义。
str [i] == '\ 0'是C字符串风格的概念。在C字符串的实现中,字符串的最后一个字符是'\ 0',以标记C字符串的结尾。
对于C字符串,您通常必须使用单独的变量“记住”字符串的长度。在C ++ String中,您可以将任何位置分配为'\ 0'。
以下是一个可供测试的代码段:
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char* argv[]) {
char str[5] = "abc";
cout << str << " length: " << strlen(str) << endl;
cout << "char at 4th position: " << str[3] << "|" << endl;
cout << "char at 5th position: " << str[4] << "|" << endl;
str[4]='X'; // this is OK, since Cstring is just an array of char!
cout << "char at 5th position after assignment: " << str[4] << "|" << endl;
string cppstr("abc");
cppstr.resize(3);
cout << "cppstr: " << cppstr << " length: " << cppstr.length() << endl;
cout << "char at 4th position:" << cppstr[3] << endl;
cout << "char at 401th positon:" << cppstr[400] << endl;
// you should be getting segmentation fault in the
// above two lines! But this may not happen every time.
cppstr[0] = '\0';
str[0] = '\0';
cout << "After zero the first char. Cstring: " << str << " length: " << strlen(str) << " | C++String: " << cppstr << " length: " << cppstr.length() << endl;
return 0;
}
abc length: 3
char at 4th position: |
char at 5th position: |
char at 5th position after assignment: X|
cppstr: abc length: 3
char at 4th position:
char at 401th positon:?
After zero the first char. Cstring: length: 0 | C++String: bc length: 3
std::string
不需要以 '\0' 结尾。 - apple applestr[str.size()]
总是'\0'
(如下所讨论)。 - Lightness Races in Orbitstd::string str{"\0foo", 4}
这样的字符串中。与C风格的字符串不同,std::string
可以包含嵌入式的NUL字符。 - Tavian Barnes