2015-03-30 1 views
3

Selon les déclarations faites dans les réponses de ces questionsest-il un moyen de définir la longueur d'une chaîne std :: sans modifier le contenu de la mémoire tampon?

.. en C++ 11, il devrait être possible d'appeler une API C fonction qui prend un pointeur char pour stocker la sortie comme ceci:

str::string str; 
str.reserve(SOME_MAX_VALUE); 
some_C_API_func(&str[0]); 

Mais existe-t-il maintenant un moyen légal pour de définir la taille de la chaîne à la longueur du contenu (terminé par un caractère nul) dans le tampon? Quelque chose comme ceci:

str.set_size(strlen(&str[0])); 

Ceci est très inesthétique abus de std::string de toute façon je vous entends dire, mais je ne peux pas créer un tampon char temporaire sur pile, donc je dois créer un tampon en tas et détruire après (que je veux éviter).

Existe-t-il une bonne façon de faire cela? Peut-être pas réserver mais le redimensionnement et d'appeler erase() serait ensuite le faire, mais il ne se sent pas bien plus propre ..

+0

Avez-vous essayé 'redimensionner '? –

+0

oui, mais 'resize()' semble modifier le contenu. Au moins quand je réserve() 'le tampon et' resize() 'après cela la chaîne est vide après. Il semble fonctionner avec 'resize (SOME_MAX_VALUE)'. Si quelqu'un me convainc que c'est l'approche la plus sophistiquée, je suis heureux :) – frans

+0

@frans, pourquoi n'utilisez-vous pas std :: array pour définir la taille de la chaîne ?? – MCHAppy

Répondre

6

Vous devez utiliser resize() pas reserve(), puis de nouveau resize() pour régler la longueur finale.

Sinon, lorsque vous resize() de zéro au résultat retourné par strlen() le tableau sera rempli avec zéro caractère, en écrasant ce que vous avez écrit dedans. La chaîne est autorisée à le faire, car elle suppose (correctement) que tout, de la taille actuelle à la capacité réservée actuelle, est une donnée non initialisée qui ne contient rien. Pour que la chaîne sache que les caractères sont effectivement valides et que leur contenu doit être conservé, vous devez utiliser initialement resize() et non reserve(). Puis, quand vous aurez à nouveau réduit la chaîne de caractères à resize(), elle ne tronquera que la fin indésirable de la chaîne et ajoutera une terminaison nulle, elle ne remplacera pas ce que vous avez écrit dedans.

N.B. le resize() initial remplira zéro la chaîne, ce qui n'est pas strictement nécessaire dans votre cas parce que vous allez écraser la partie qui vous intéresse et ensuite jeter le reste de toute façon. Si les chaînes sont très longues et que le profilage montre que le remplissage par zéro est un problème, vous pouvez le faire à la place:

std::unique_ptr<char[]> str(new char[SOME_MAX_VALUE]); 
some_C_API_func(str.get()); 
+0

L'approche avec 'unique_ptr' ne permet pas, par ex. compare les chaînes en utilisant 'operator =='. – Ruslan