Supprimer le dernier caractère de la chaîne C ++

210

Comment supprimer le dernier caractère d'une chaîne C ++?

J'ai essayé st = substr(st.length()-1);Mais ça n'a pas marché.

skazhy
la source
6
Voulez-vous une nouvelle chaîne avec le dernier caractère supprimé ou la même chaîne sans le dernier caractère?
Matthieu M.
Pour une CString MFC Visual C ++: CString str=CString("Hello world"); str.Delete(str.GetLength()-1);
sergiol

Réponses:

193

Pour une version non mutante:

st = myString.substr(0, myString.size()-1);
Matthieu M.
la source
20
@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:

st.pop_back();
mpgaillard
la source
49
c'est pour c ++ 11!
Amir
1
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.

BTW - N'y a-t-il vraiment pas std :: string :: pop_back? - semble étrange.

Steve314
la source
11
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.

RC.
la source
8
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?
ribamar
17

str.erase( str.end()-1 )

Référence: std :: string :: erase () prototype 2

aucun c ++ 11 ou c ++ 0x n'est nécessaire.

ribamar
la source
1
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'.
Deqing
1
facilement str[str.length()-1] = 0; str.erase(str.end()-1);
réparable
5
@Dequing: votre exemple n'est pas valide. L'effacement réduit la taille de la chaîne, donc l'accès à s[2]est illégal.
EML
11

C'est tout ce dont vous avez besoin:

#include <string>  //string::pop_back & string::empty

if (!st.empty())
    st.pop_back();
jcrv
la source
9
int main () {

  string str1="123";
  string str2 = str1.substr (0,str1.length()-1);

  cout<<str2; // output: 12

  return 0;
}
codaddict
la source
2

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:

if (!st.empty())
  st.erase(std::prev(st.end())); // Erase element referred to by iterator one
                                 // before the end
Michael Goldshteyn
la source
2

str.erase(str.begin() + str.size() - 1)

str.erase(str.rbegin()) ne compile malheureusement pas, car reverse_iterator ne peut pas être converti en un normal_iterator.

C ++ 11 est votre ami dans ce cas.

Zèbre
la source
Cette méthode a également un problème, le dernier caractère n'est pas défini sur '\ 0'.
Deqing
1
Une raison particulière pour ne pas le faire str.erase(str.end() - 1)?
vallentin
-4

Si la longueur est non nulle, vous pouvez également

str[str.length() - 1] = '\0';
Jan Glaser
la source
4
La définition du dernier caractère sur \0ne modifie pas la longueur de la chaîne. str.length()sera inexact.
2018
Oui, je le vois maintenant. Nous envisageons C ++. Vous avez raison, cela ne change pas la longueur de la chaîne
Jan Glaser