@MatthieuM. Votre exemple est déroutant, je pense que l'essence de la question est de modifier la chaîne d'origine, dans votre exemple, vous ne modifiez pas la chaîne d'origine, car dans votre exemple, la chaîne d'origine est appelée "myString", ce qui donne à la confusion, dans la question c'est "st". Votre code doit être: st = st.substr(0, st.size()-1). Mais il ne semble toujours pas la bonne, je pense que la bonne façon est d'utiliser la fonction qui est destinée à cette tâche, il est appelé effacement () et le code est: st.erase(st.size()-1). Cela s'appellerait une "version mutante".
Czarek Tomczak
1
@CzarekTomczak: Je comprends que ce n'est pas exactement ce qui a été demandé, d'où l'avertissement avant l'essentiel.
Matthieu M.
2
@MattPhillips: sa solution est spécifique à C ++ 11 ( pop_backn'existait pas en C ++ 03) et c'est aussi une modification sur place (et l'OP n'a jamais précisé s'il voulait ou non sur place) ... comme tel, il a une bonne réponse, mais pas la seule possible.
Matthieu M.
404
Solution simple si vous utilisez C ++ 11. Probablement O (1) également:
En tant que FYI - sa prise en charge uniquement à partir de GCC 4.7 (bien sûr avec le commutateur de compilation -std = c ++ 11)
Shmil The Cat
20
N'oubliez pas de vérifier length().
Oui, il apparaît trop loin sur la page ..!
James Bedford
1
The behavior is undefined if the string is empty. d' ici
Raffi
24
if(str.size ()>0) str.resize (str.size ()-1);
Une alternative à std :: erase est bonne, mais j'aime le "- 1" (qu'il soit basé sur une taille ou un itérateur final) - pour moi, cela aide à exprimer l'intention.
Il n'y std::string::pop_backen a pas en C ++ 03; il a cependant été ajouté en C ++ 0x.
James McNellis
OK merci. Cela a causé un peu de confusion - je pourrais jurer que je l'ai utilisé, mais il n'est pas là. Peut-être que j'ai une bibliothèque non standard dans un compilateur quelque part (entre VC ++ 2003, VC ++ 2008, MinGW GCC3 MinGW GCC 4 et Linux GCC 4, vous obtenez quelques différences). Plus probablement, je me confond simplement avec d'autres types.
Steve314
resize () n'est probablement pas destiné à une telle utilisation, c'est une fonction liée à la mémoire, erase () sert à supprimer des caractères.
Czarek Tomczak
3
@Czarek Tomczak - désolé pour la réponse absurdement tardive, mais resizec'est une fonction de redimensionnement, et non plus une fonction de mémoire que toute autre chose qui pourrait augmenter la mémoire nécessaire. Par exemple, si vous avez resizeune taille plus petite, cela ne réduira pas la mémoire réservée. Je pense que vous pensez à reserve, ce qui pourrait au moins réduire la mémoire allouée si on vous le demande - voir redimensionner ici et réserver ici .
Steve314
3
si (! str.empty ()) est préféré à la taille
ericcurtin
19
buf.erase(buf.size()-1);
Cela suppose que vous savez que la chaîne n'est pas vide. Si c'est le cas, vous obtiendrez une out_of_rangeexception.
buf [buf.size () - 1] = '\ 0'; ne supprime rien - il change juste le caractère qui était là pour avoir la valeur zéro. std:; les chaînes peuvent heureusement contenir de tels caractères.
Neil a raison. J'aurais probablement dû clarifier cela dans ma réponse. La deuxième option modifiera efficacement la valeur du dernier caractère afin qu'il ne s'imprime pas, mais la longueur de la chaîne restera la même. L'utilisation de l'effacement "supprime" en fait le dernier caractère et changera la taille de la chaîne.
RC.
@RC Il sera imprimé, en supposant que vous utilisez quelque chose comme cout << buf. Son apparence dépendra de votre plateforme. Et vous pouvez toujours clarifier en modifiant votre réponse.
Qu'y a-t-il de mieux à la size() place end()d'une autre réponse?
Cela peut conduire à une situation étrange: la taille de la chaîne a été réduite mais le dernier caractère n'est pas défini sur '\ 0'.
Deqing
1
@Deqing pouvez-vous donner plus de détails sur ce qui se passe dans ce cas?
ribamar
Par exemple , si vous avez string s("abc");, après effacement , il semble fonctionner: cout<<s; // prints "ab"cependant, le dernier caractère est toujours là: cout<<s[2]; // still prints 'c'.
CString str=CString("Hello world"); str.Delete(str.GetLength()-1);
Réponses:
Pour une version non mutante:
la source
st = st.substr(0, st.size()-1)
. Mais il ne semble toujours pas la bonne, je pense que la bonne façon est d'utiliser la fonction qui est destinée à cette tâche, il est appelé effacement () et le code est:st.erase(st.size()-1)
. Cela s'appellerait une "version mutante".pop_back
n'existait pas en C ++ 03) et c'est aussi une modification sur place (et l'OP n'a jamais précisé s'il voulait ou non sur place) ... comme tel, il a une bonne réponse, mais pas la seule possible.Solution simple si vous utilisez C ++ 11. Probablement O (1) également:
la source
length()
.The behavior is undefined if the string is empty.
d' iciUne alternative à std :: erase est bonne, mais j'aime le "- 1" (qu'il soit basé sur une taille ou un itérateur final) - pour moi, cela aide à exprimer l'intention.
BTW - N'y a-t-il vraiment pas std :: string :: pop_back? - semble étrange.
la source
std::string::pop_back
en a pas en C ++ 03; il a cependant été ajouté en C ++ 0x.resize
c'est une fonction de redimensionnement, et non plus une fonction de mémoire que toute autre chose qui pourrait augmenter la mémoire nécessaire. Par exemple, si vous avezresize
une taille plus petite, cela ne réduira pas la mémoire réservée. Je pense que vous pensez àreserve
, ce qui pourrait au moins réduire la mémoire allouée si on vous le demande - voir redimensionner ici et réserver ici .Cela suppose que vous savez que la chaîne n'est pas vide. Si c'est le cas, vous obtiendrez une
out_of_range
exception.la source
size()
placeend()
d'une autre réponse?str.erase( str.end()-1 )
Référence: std :: string :: erase () prototype 2
aucun c ++ 11 ou c ++ 0x n'est nécessaire.
la source
string s("abc");
, après effacement , il semble fonctionner:cout<<s; // prints "ab"
cependant, le dernier caractère est toujours là:cout<<s[2]; // still prints 'c'
.str[str.length()-1] = 0; str.erase(str.end()-1);
s[2]
est illégal.C'est tout ce dont vous avez besoin:
la source
la source
Avec C ++ 11, vous n'avez même pas besoin de la longueur / taille. Tant que la chaîne n'est pas vide, vous pouvez effectuer les opérations suivantes:
la source
str.erase(str.begin() + str.size() - 1)
str.erase(str.rbegin())
ne compile malheureusement pas, carreverse_iterator
ne peut pas être converti en un normal_iterator.C ++ 11 est votre ami dans ce cas.
la source
str.erase(str.end() - 1)
?Si la longueur est non nulle, vous pouvez également
la source
\0
ne modifie pas la longueur de la chaîne.str.length()
sera inexact.