Comment voulez-vous construire un std::string avec un intégré à null?
Si je veux construire un std::string avec une ligne comme:
std::string my_string("astd::string my_string("a\0b");
b");
Où je veux avoir trois caractères dans la chaîne résultante (a, null, b), je n'en obtenir un. Quelle est la bonne syntaxe?
Vous devrez être prudent avec cela. Si vous remplacez 'b' avec un caractère numérique, vous silencieusement créer la mauvaise chaîne. Voir: stackoverflow.com/questions/10220401/...
OriginalL'auteur Bill | 2008-10-02
Vous devez vous connecter pour publier un commentaire.
Depuis C++14
nous avons été en mesure de créer littérale
std::string
Avant Le C++14
Le problème est le
std::string
constructeur qui prend unconst char*
suppose l'entrée est un C-string. C-les cordes sont\0
terminée et donc l'analyse s'arrête quand il atteint le\0
caractère.Pour compenser cela, vous devez utiliser le constructeur qui construit la chaîne de caractères à partir d'un char array (pas un C-String). Elle prend deux paramètres - un pointeur vers le tableau et d'une longueur:
Remarque: C++
std::string
est PAS\0
terminée (comme expliqué dans d'autres posts). Cependant, vous pouvez extraire un pointeur vers une mémoire tampon interne qui contient un C-String avec la méthodec_str()
.Également vérifier Doug T répondre ci-dessous sur l'utilisation d'un
vector<char>
.Également vérifier RiaD pour un C++14 solution.
Ils sont nul en termes de stockage, mais pas dans le sens qu'ils sont null significatifs de fin null (c'est à dire avec de la ficelle de la longueur de la définition de la sémantique), qui est le sens habituel du terme.
Bien expliqué. Je vous remercie.
OriginalL'auteur Martin York
Si vous faites de la manipulation comme vous le feriez avec un style c string (tableau de caractères) envisager d'utiliser
Vous avez plus de liberté à le traiter comme un tableau de la même manière que vous le feriez à un c-string. Vous pouvez utiliser la copie() pour copier une chaîne de caractères:
et vous pouvez l'utiliser dans les mêmes endroits que vous pouvez utiliser c-strings
Naturellement, cependant, vous souffre des mêmes problèmes que c-strings. Vous pouvez oublier votre null terminal ou écrire passé l'espace alloué.
byte *bytes = new byte[dataSize]; std::memcpy(bytes, image.data, dataSize * sizeof(byte)); std::string test(reinterpret_cast<char *>(bytes)); std::cout << "Encoded String length " << test.length() << std::endl;
OriginalL'auteur Doug T.
Je n'ai aucune idée de pourquoi vous voulez faire une telle chose, mais essayez ceci:
Parce que les gens ont à travailler avec des données binaires, parfois?
ensuite, vous faites quelque chose de mal si vous êtes à stocker des données binaires comme une chaîne de caractères. C'est ce que
vector<unsigned char>
ouunsigned char *
ont été inventés pour.Je suis tombé sur ce, tout en essayant d'en apprendre plus sur la sécurité de chaînes de caractères. J'ai voulu tester mon code pour s'assurer qu'il fonctionne toujours, même si il lit un caractère nul dans pendant la lecture d'un fichier / network qu'il s'attend à des données textuelles. J'utilise
std::string
pour indiquer que les données doivent être considérées comme du simple texte, mais je suis en train de faire certains de hachage et je tiens à vous assurer que tout fonctionne encore avec des caractères null impliqués. Qui semble que l'utilisation d'un littéral de chaîne avec un intégré à caractère null.Non, ce n'est pas vrai. Un
\0
d'octets en une chaîne UTF-8 ne peut être NUL. Un multi-octets caractère codé, ils ne contiennent\0
--ni aucun autre caractère ASCII pour cette question.OriginalL'auteur 17 of 26
Quelles nouvelles capacités définies par l'utilisateur littéraux ajouter à C++? présente un élégant réponse: Définir
ensuite, vous pouvez créer votre chaîne de cette façon:
ou même ainsi:
Il y a un "style ancien" chemin:
ensuite, vous pouvez définir
OriginalL'auteur anonym
La suite...
jk, merci, j'ai corrigé...
OriginalL'auteur Andrew Stein
Vous devrez être prudent avec cela. Si vous remplacez 'b' avec un caractère numérique, vous silencieusement créer la mauvaise chaîne à l'aide de la plupart des méthodes. Voir: Règles pour le C++ littéraux de chaîne de caractère d'échappement.
Par exemple, j'ai laissé tomber cette innocente à la recherche extrait au moyen d'un programme
Ici est ce que ce programme de sortie pour moi:
C'était ma première instruction d'impression deux fois, plusieurs caractères non imprimables, suivie par un retour à la ligne, suivie par quelque chose dans la mémoire interne, dont je viens de écrasait (et puis imprimé, montrant qu'il a été remplacé). Le pire de tout, même de la compilation avec complet et détaillé de gcc avertissements m'a donné aucune indication de quelque chose de mauvais, et l'exécution du programme par le biais de valgrind ne pas se plaindre d'une mauvaise mémoire des schémas d'accès. En d'autres termes, il est complètement indétectable par des outils modernes.
Vous pouvez obtenir ce même problème avec le beaucoup plus simple
std::string("0", 100);
, mais l'exemple ci-dessus est un peu plus délicat, et donc plus difficile à voir quel est le problème.Heureusement, C++11 nous donne une bonne solution pour le problème à l'aide d'initialiseur de syntaxe de la liste. Cela vous évite d'avoir à spécifier le nombre de caractères (qui, comme je l'ai montré ci-dessus, vous pouvez le faire à tort), et évite de combiner échappé numéros.
std::string str({'a', '\0', 'b'})
est sûr pour n'importe quelle chaîne de contenu, à la différence des versions qui prennent un tableau dechar
et une taille.OriginalL'auteur David Stone
En C++14, vous pouvez maintenant utiliser les littéraux
auto s{"a\0b"s};
Belle réponse Merci.
OriginalL'auteur RiaD
Préférable d'utiliser std::vector<char> si cette question n'est pas seulement pour des fins éducatives.
OriginalL'auteur Harold Ekstrom
anonym la réponse est excellente, mais il y a un non-macro solution en C++98:
Avec cette fonction,
RawString(/* literal */)
va produire la même chaîne queS(/* literal */)
:En outre, il y a un problème avec la macro: l'expression n'est pas réellement un
std::string
comme l'écrit, et par conséquent ne peut pas être utilisé par exemple pour la simple affectation-initialisation:...donc, il pourrait être préférable d'utiliser:
Évidemment que vous ne devez utiliser l'une ou l'autre solution dans votre projet et de l'appeler ce que vous pensez est approprié.
OriginalL'auteur Kyle Strand
Je sais que c'est un temps cette question a été posée. Mais pour toute personne qui est d'avoir un problème similaire pourrait être intéressé par le code suivant.
OriginalL'auteur Dil09
Presque toutes les implémentations de std::les chaînes de caractères sont nul, de sorte que vous ne devriez probablement pas le faire. Note qu'un "\0b" est en fait de quatre caractères à cause de l'automatique terminateur null (a, null, b, null). Si vous voulez vraiment faire cette pause et std::string du contrat, vous pouvez le faire:
mais si vous le faites, tous vos amis vont se moquer de vous, vous ne trouverez jamais le vrai bonheur.
Il n'est pas nécessaire, mais dans presque toutes les implémentations, il est probablement en raison de la nécessité pour le c_str() accesseur pour vous fournir la valeur null équivalent.
Pour l'efficacité d'un caractère null être conservés sur le dos de la mémoire tampon de données. Mais aucun des opérations (c'est à dire des méthodes) sur une chaîne d'utiliser cette connaissance ou qui sont touchés par une chaîne de caractères contenant un caractère NUL. Le caractère NULL sera manipulé exactement de la même manière que n'importe quel autre caractère.
C'est pourquoi il est si drôle que la chaîne est std:: - son comportement n'est pas défini sur n'IMPORTE quelle plateforme.
Je souhaite user595447 était toujours là afin que je puisse leur demander à quoi ils ont pensé qu'ils étaient en train de parler.
OriginalL'auteur Jurney