J'ai passé environ 4 heures hier à essayer de résoudre ce problème dans mon code. J'ai simplifié le problème à l'exemple ci-dessous.Pourquoi std :: ends provoque-t-il l'échec de la comparaison de chaînes?
L'idée est de stocker une chaîne dans un train de chaînes se terminant par std :: ends, puis de la récupérer plus tard et de la comparer à la chaîne d'origine.
#include <sstream> #include <iostream> #include <string> int main(int argc, char** argv) { const std::string HELLO("hello"); std::stringstream testStream; testStream << HELLO << std::ends; std::string hi = testStream.str(); if(HELLO == hi) { std::cout << HELLO << "==" << hi << std::endl; } return 0; }
Comme vous pouvez probablement deviner, le code ci-dessus lors de l'exécution n'imprimera rien. Bien que, s'ils sont imprimés ou regardés dans le débogueur (VS2005), HELLO et hi soient identiques, leur .length() diffère en fait de 1. C'est ce que je devine qui provoque l'opérateur "==" échouer.
Ma question est pourquoi. Je ne comprends pas pourquoi std :: ends est un caractère invisible ajouté à la chaîne hi, rendant hi et HELLO différentes longueurs même si elles ont un contenu identique. De plus, ce caractère invisible ne sera pas coupé avec la réduction de boost. Cependant, si vous utilisez strcmp pour comparer .c_str() des deux chaînes, la comparaison fonctionne correctement.
La raison pour laquelle j'ai utilisé std :: ends en premier lieu est parce que j'ai eu des problèmes dans le passé avec la stringstream retenant les données parasites à la fin du flux. std :: ends a résolu ça pour moi.
D'accord, je comprends la mécanique derrière, mais je n'aime pas la sémantique. Il semble que j'ai deux choix: n'utilisez pas std :: ends et risquez d'avoir des données parasites, ou bien utilisez-le et ajoutez du code personnalisé pour vous débarrasser des caractères NULL supplémentaires. –
Vous devez essayer de concevoir votre code pour connaître les attentes des chaînes. Par exemple, si vous lisez des chaînes à partir d'un périphérique réseau, elles ne sont probablement pas terminées, mais cela dépend de l'API que vous utilisiez, mais Si vous passez des chaînes dans votre application, elles le sont probablement. Ne vous mettez pas dans une situation où vous n'avez aucune idée de ce qu'il y a dans vos données. –
Pourquoi utilisez-vous les extrémités de toute façon? Cela est uniquement utilisé lorsque vous créez une chaîne de style C terminée par un caractère nul à partir de données brutes. Ici, dans votre exemple, ce n'est clairement pas approprié. Vous avez déjà une chaîne C++. –