La documentation est correcte. À utiliser c_str()
si vous voulez une chaîne terminée par null.
Si les implémenteurs arrivent à implémenter data()
en termes de que c_str()
vous n'avez pas à vous inquiéter, utilisez toujours data()
si vous n'avez pas besoin que la chaîne soit terminée par null, dans certaines implémentations, il peut s'avérer plus performant que c_str ().
les chaînes ne doivent pas nécessairement être composées de données de caractère, elles peuvent être composées d'éléments de n'importe quel type. Dans ces cas, data()
c'est plus significatif. c_str()
à mon avis, ce n'est vraiment utile que lorsque les éléments de votre chaîne sont basés sur des caractères.
Extra : à partir de C ++ 11, les deux fonctions doivent être identiques. c'est-à data
- dire qu'il doit maintenant être terminé par zéro. Selon cppreference : "Le tableau retourné est terminé par un null, c'est-à-dire que data () et c_str () exécutent la même fonction."
.data()
non constante pour , donc elles ne sont plus équivalentes pour les chaînes non constantes.Dans C ++ 11 / C ++ 0x ,
data()
etc_str()
n'est plus différent. Et donc ildata()
est également nécessaire d'avoir une terminaison nulle à la fin.la source
std::string
allouer un supplémentchar
pour une fin'\0'
. Lorsque vous le faitesstd::string s("\0");
, les deuxs.data()[0]
ets.data()[1]
sont garantis d'évaluer à 0.Même si vous avez vu qu'ils font de même, ou que .data () appelle .c_str (), il n'est pas correct de supposer que ce sera le cas pour d'autres compilateurs. Il est également possible que votre compilateur change avec une future version.
2 raisons d'utiliser std :: string:
std :: string peut être utilisé à la fois pour du texte et des données binaires arbitraires.
Vous devez utiliser la méthode .c_str () lorsque vous utilisez votre chaîne comme exemple 1.
Vous devez utiliser la méthode .data () lorsque vous utilisez votre chaîne comme exemple 2. Non pas parce qu'il est dangereux d'utiliser .c_str () dans ces cas, mais parce qu'il est plus explicite que vous travaillez avec des données binaires pour que d'autres vérifient votre code.
Piège possible avec l'utilisation de .data ()
Le code suivant est incorrect et peut provoquer une erreur de segmentation dans votre programme:
Pourquoi est-il courant pour les développeurs de faire faire la même chose à .data () et .c_str ()?
Parce qu'il est plus efficace de le faire. La seule façon de faire en sorte que .data () renvoie quelque chose qui n'est pas terminé par null serait d'avoir .c_str () ou .data () copier leur tampon interne, ou d'utiliser simplement 2 tampons. Avoir un seul tampon terminé par null signifie toujours que vous pouvez toujours utiliser un seul tampon interne lors de l'implémentation de std :: string.
la source
Il a déjà été répondu, quelques notes sur le but: Liberté de mise en œuvre.
std::string
les opérations - par exemple l'itération, la concaténation et la mutation d'élément - n'ont pas besoin du terminateur zéro. Sauf si vous passez lestring
à une fonction qui attend une chaîne terminée par zéro, il peut être omis.Cela permettrait à une implémentation d'avoir des sous-chaînes partager les données de chaîne réelles:
string::substr
pourrait contenir en interne une référence aux données de chaîne partagées et la plage de début / fin, évitant la copie (et l'allocation supplémentaire) des données de chaîne réelles. L'implémentation reporterait la copie jusqu'à ce que vous appeliez c_str ou modifiez l'une des chaînes. Aucune copie ne serait jamais faite si les strigns impliqués sont simplement lus.(l'implémentation de copie sur écriture n'est pas très amusante dans les environnements multithreads, et les économies de mémoire / allocation typiques ne valent pas le code plus complexe aujourd'hui, donc c'est rarement fait).
De même,
string::data
permet une représentation interne différente, par exemple une corde (liste chaînée de segments de chaîne). Cela peut améliorer considérablement les opérations d'insertion / remplacement. encore une fois, la liste des segments devrait être réduite en un seul segment lorsque vous appelezc_str
oudata
.la source
Citation de
ANSI ISO IEC 14882 2003
(C ++ 03 Standard):la source
Tous les commentaires précédents sont cohérents, mais j'aimerais également ajouter qu'à partir de c ++ 17, str.data () renvoie un char * au lieu de const char *
la source
const
et lesnon-const
surcharges sont disponibles depuis C ++ 17.