web-dev-qa-db-fra.com

Différence entre string.empty et string [0] == '\ 0'

Supposons que nous ayons une chaîne

std::string str; // some value is assigned

Quelle est la différence entre str.empty() et str[0] == '\0'?

63
Pro Account

C++ 11 et au-delà

string_variable[0] Est requis pour retourner le caractère nul si la chaîne est vide. De cette façon, il n'y a pas de comportement indéfini et la comparaison fonctionne toujours si la chaîne est vraiment vide. Cependant, vous pourriez avoir une chaîne commençant par un caractère nul ("\0Hi there") Qui renvoie true même si elle n'est pas vide. Si vous voulez vraiment savoir s'il est vide, utilisez empty().


Pré-C++ 11

La différence est que si la chaîne est vide, alors string_variable[0] A un comportement indéfini; Il n'y a pas d'index 0 sauf si la chaîne est qualifiée const. Si la chaîne estconst qualifiée, elle renverra un caractère nul.

string_variable.empty() d'autre part retourne vrai si la chaîne est vide, et faux si ce n'est pas le cas; le comportement ne sera pas indéfini.


Sommaire

empty() est destiné à vérifier si la chaîne/conteneur est vide ou non. Il fonctionne sur tous les conteneurs qui le fournissent et l'utilisation de empty indique clairement votre intention - ce qui signifie beaucoup pour les personnes qui lisent votre code (y compris vous).

91
NathanOliver

Depuis C++ 11, il est garanti que str[str.size()] == '\0'. Cela signifie que si une chaîne est vide, alors str[0] == '\0'. Mais une chaîne C++ a un champ de longueur explicite, ce qui signifie qu'elle peut contenir des caractères nuls incorporés.

Par exemple. pour std::string str("\0ab", 3), str[0] == '\0' mais str.empty() est faux.

De plus, str.empty() est plus lisible que str[0] == '\0'.

36
Oberon

Les autres réponses ici sont 100% correctes. Je veux juste ajouter trois autres notes:

empty est générique (chaque conteneur STL implémente cette fonction) tandis que operator [] avec size_t ne fonctionne qu'avec des objets chaîne et des conteneurs de type tableau. lorsqu'il s'agit de code STL générique, empty est préférable.

de plus, empty est assez explicite alors que =='\0' ne l'est pas beaucoup. quand il est 2 heures du matin et que vous déboguez votre code, préférez-vous voir if(str.empty()) ou if(str[0] == '\0')? si seule la fonctionnalité compte, nous écrirons tous dans Vanilla Assembly.

il y a aussi une pénalité de performance impliquée. empty est généralement implémenté en comparant le membre de taille de la chaîne à zéro, ce qui est très bon marché, facile à aligner, etc. la comparaison avec le premier caractère peut être plus lourde. tout d'abord, puisque toutes les chaînes implémentent optimisation des chaînes courtes, le programme doit d'abord demander si la chaîne est en "mode court" ou "mode long". ramification - pire performance. si la chaîne est longue, le déréférencement peut être coûteux si la chaîne a été "ignorée" pendant un certain temps et la déréférence elle-même peut provoquer un défaut de cache qui est coûteux.

24
David Haim

empty () n'est pas implémenté comme recherchant l'existence d'un caractère nul à la position 0, son simple

bool empty() const
{
    return size() == 0 ;
}

Ce qui pourrait être différent

6
MyDeveloperDay

Méfiez-vous également des fonctions que vous utiliserez si vous utilisez C++ 11 ou une version ultérieure:

#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;
}

reviendra

La taille de str est de 3 octets.

La taille de str est de 3 long.

La taille de str est longue de 0.

4
Thomas Ayoub

La chaîne C++ a le concept de savoir si elle est vide ou non. Si la chaîne est vide, alors str [0] n'est pas défini. Uniquement si la chaîne C++ a une taille> 1, str [0] est défini.

str [i] == '\ 0' est un concept du style C-string. Dans l'implémentation de la chaîne C, le dernier caractère de la chaîne est '\ 0' pour marquer la fin d'une chaîne C.
Pour la chaîne C, vous devez généralement vous "souvenir" de la longueur de votre chaîne avec une variable distincte. Dans C++ String, vous pouvez attribuer n'importe quelle position avec '\ 0'.

Juste un segment de code pour jouer avec:

#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;
}

Sur ma machine la sortie:

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
3
Kemin Zhou

Vous voulez connaître la différence entre str.empty() and str[0] == '\0'. Suivons l'exemple:

#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;
}

Sortie:

str is empty
str2 contains: alues

str.empty() vous indiquera que la chaîne est vide ou non et str[0] == '\0' vous informera que votre index de chaînes 0 contient '\0' ou non. Votre index de variables de chaîne 0 contient '\0' Ne signifie pas que votre chaîne est vide. Oui, seulement une fois que cela peut être possible lorsque la longueur de votre chaîne est 1 et que votre index de variables de chaîne 0 contient '\0'. Cette fois, vous pouvez dire que c'est une chaîne vide.

2
Anower Perves