Предположим, что у нас есть строка
std::string str; // some value is assigned
В чем разница между str.empty()
и str[0] == '\0'
?
Предположим, что у нас есть строка
std::string str; // some value is assigned
В чем разница между str.empty()
и str[0] == '\0'
?
string_variable[0]
требуется вернуть нулевой символ, если строка пуста. Таким образом, поведение undefined отсутствует, и сравнение все еще работает, если строка действительно пуста. Однако у вас может быть строка, которая начинается с нулевого символа ("\0Hi there"
), который возвращает true
, хотя он не пуст. Если вы действительно хотите узнать, пуст ли он, используйте empty()
.
Разница в том, что если строка пуста, то string_variable[0]
имеет поведение undefined; Нет индекса 0, если строка const
-qualified. Если строка const
квалифицирована, то она вернет нулевой символ.
string_variable.empty()
, с другой стороны, возвращает true, если строка пуста, а false, если это не так; поведение не будет undefined.
empty()
предназначен для проверки, является ли строка/контейнер пустой или нет. Он работает на всех контейнерах, которые его предоставляют, и используя empty
четко заявляет о своем намерении, что очень много значит для людей, читающих ваш код (включая вас).
Так как С++ 11 гарантируется, что str[str.size()] == '\0'
. Это означает, что если строка пуста, то str[0] == '\0'
. Но строка С++ имеет явное поле длины, то есть оно может содержать внедренные нулевые символы.
например. для std::string str("\0ab", 3)
, str[0] == '\0'
, но str.empty()
является ложным.
Кроме того, str.empty()
более читаем, чем str[0] == '\0'
.
Другие ответы здесь на 100% правильные. Я просто хочу добавить еще три примечания:
empty
является общим (каждый контейнер STL реализует эту функцию), а operator []
с size_t
работает только со строковыми объектами и контейнерами, подобными массивам. при работе с общим кодом STL предпочтительнее empty
.
Кроме того, empty
в значительной степени объясняет себя, а =='\0'
не очень много.
когда он 2AM и вы отлаживаете свой код, предпочитаете ли вы видеть if(str.empty())
или if(str[0] == '\0')
?
если только функциональность имеет значение, мы все будем писать в ванильной сборке.
также применяется штраф за исполнение. empty
обычно реализуется путем сравнения элемента размера строки с нолем, который очень дешев, легко встроен и т.д., сравнивая с первым символом, может быть более тяжелым. прежде всего, поскольку все строки реализуют короткую оптимизацию строк, программа сначала должна спросить, находится ли строка в "коротком режиме" или "длинном режиме". ветвление - хуже производительность. если строка длинна, разыменование ее может быть дорогостоящим, если строка была "проигнорирована" в течение некоторого времени, а сама разыменова может вызвать кэш-ошибку, которая является дорогостоящей.
empty() не реализуется как поиск существования нулевого символа в позиции 0, его просто
bool empty() const
{
return size() == 0 ;
}
Что может быть другим
Кроме того, будьте осторожны с функциями, которые вы будете использовать, если используете С++ 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 [0] - undefined. Только если строка С++ имеет размеp > 1, определяется str [0].
str [i] == '\ 0' - это понятие стиля C-строки. В реализации C-строки последним символом строки является "\ 0", чтобы пометить конец 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
Вы хотите узнать разницу между str.empty() and 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'
. На этот раз вы можете сказать, что это пустая строка.