Remova o último caractere da string C ++

210

Como posso remover o último caractere de uma string C ++?

Eu tentei st = substr(st.length()-1);Mas não funcionou.

skazhy
fonte
6
Deseja uma nova string com o último caractere removido ou a mesma string sem o último caractere?
Matthieu M.
Para um MFC Visual C ++ CString: CString str=CString("Hello world"); str.Delete(str.GetLength()-1);
sergiol 11/11

Respostas:

193

Para uma versão sem mutação:

st = myString.substr(0, myString.size()-1);
Matthieu M.
fonte
20
@MatthieuM. Seu exemplo é confuso, acho que a essência da pergunta é modificar a string original. No seu exemplo, você não está modificando a string original, porque no seu exemplo a string original é chamada "myString", o que gera confusão. na pergunta é "st". O código deve ser: st = st.substr(0, st.size()-1). Mas ainda não parece o caminho certo, eu acho que a maneira correta é usar a função que se pretende para esta tarefa, é chamado de apagar () e o código é: st.erase(st.size()-1). Isso seria chamado de "versão mutante".
Czarek Tomczak
1
@CzarekTomczak: Entendo que isso não é exatamente o que foi solicitado, portanto o aviso antes da essência.
Matthieu M.
2
@MattPhillips: sua solução é específica para C ++ 11 ( pop_backnão existia no C ++ 03) e também é uma modificação no local (e o OP nunca esclareceu se ele queria o local ou não) ... como assim, ele tem uma resposta correta, mas não a única possível.
Matthieu M.
404

Solução simples se você estiver usando o C ++ 11. Provavelmente também o tempo O (1):

st.pop_back();
mpgaillard
fonte
49
isto é para c ++ 11!
Amir
1
Como um FYI - está sendo suportado apenas pelo GCC 4.7 (fora do curso com a opção de compilação -std = c ++ 11)
Shmil The Cat
20
Não esqueça de conferir length().
Sim, parece muito abaixo na página ..!
James Bedford
1
The behavior is undefined if the string is empty. a partir daqui
Raffi
24
if (str.size () > 0)  str.resize (str.size () - 1);

Uma alternativa std :: erase é boa, mas eu gosto do "- 1" (seja com base no tamanho ou no iterador final) - para mim, isso ajuda a expressar a intenção.

BTW - Não existe realmente std :: string :: pop_back? parece estranho.

Steve314
fonte
11
Não há std::string::pop_backno C ++ 03; foi adicionado em C ++ 0x, no entanto.
James McNellis
OK - obrigado. Isso causou um pouco de confusão - eu poderia jurar que o usei, mas não está lá. Talvez eu tenha uma biblioteca não padrão em algum compilador em algum lugar (entre VC ++ 2003, VC ++ 2008, MinGW GCC3 MinGW GCC 4 e Linux GCC 4, você obtém algumas diferenças). Provavelmente, estou apenas me confundindo com outros tipos.
21310 Steve314
resize () provavelmente não se destina a esse uso, é uma função relacionada à memória, erase () é para excluir caracteres.
Czarek Tomczak
3
@Czarek Tomczak - desculpe pela resposta absurdamente atrasada, mas resizeé uma função de redimensionamento e não mais uma função de memória que qualquer outra coisa que possa aumentar a memória necessária. Por exemplo, se você resizeusar um tamanho menor, isso não reduzirá a memória reservada. Eu acho que você está pensando reserve, o que pelo menos pode reduzir a memória alocada se solicitado - veja redimensionar aqui e reserve aqui .
precisa saber é o seguinte
3
(! str.empty ()) se é preferível ao tamanho
ericcurtin
19
buf.erase(buf.size() - 1);

Isso pressupõe que você saiba que a sequência não está vazia. Nesse caso, você receberá uma out_of_rangeexceção.

RC.
fonte
8
buf [tamanho do buf () - 1] = '\ 0'; não remove nada - apenas altera o caractere que estava lá para ter o valor zero. std:; strings podem conter felizmente esses caracteres.
Neil está correto. Eu provavelmente deveria ter esclarecido isso na minha resposta. A segunda opção alterará efetivamente o valor do último caractere, para que não seja impresso, mas o comprimento da string permanecerá o mesmo. O uso de apagar na verdade "remove" o último caractere e altera o tamanho da string.
RC.
@RC Ele será impresso, assumindo que você use algo como cout << buf. A aparência dele dependerá da sua plataforma. E você sempre pode esclarecer editando sua resposta.
O que há de melhor em size() vez end()de outra resposta?
Ribamar # 8/17
17

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

Referência: std :: string :: erase () prototype 2

não é necessário c ++ 11 ou c ++ 0x.

ribamar
fonte
1
Isso pode levar a uma situação estranha: o tamanho da string foi reduzido, mas o último caractere não está definido como '\ 0'.
Deqing
1
@ Deqing, você pode dar mais detalhes do que acontece nesse caso?
Ribamar # 26/14
Por exemplo, se tiver string s("abc");, depois de apagá-lo parece trabalhar: cout<<s; // prints "ab", no entanto, o último personagem ainda está lá: cout<<s[2]; // still prints 'c'.
Deqing 27/03
1
corrigido facilmente: apenasstr[str.length()-1] = 0; str.erase(str.end()-1);
taxiliano 19/03/2015
5
@ Dequing: seu exemplo é inválido. A exclusão reduz o tamanho da string, portanto, o acesso a s[2]é ilegal.
EML
11

É tudo o que você precisa:

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

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

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

  cout<<str2; // output: 12

  return 0;
}
codaddict
fonte
2

Com o C ++ 11, você nem precisa do comprimento / tamanho. Desde que a sequência não esteja vazia, você pode fazer o seguinte:

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

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

str.erase(str.rbegin()) infelizmente não compila, já que reverse_iterator não pode ser convertido em um normal_iterator.

C ++ 11 é seu amigo neste caso.

Zebra
fonte
Este método também tem problemas, o último caractere não está definido como '\ 0'.
Deqing
1
Alguma razão específica para não fazer str.erase(str.end() - 1)?
Vallentin
-4

Se o comprimento for diferente de zero, você também pode

str[str.length() - 1] = '\0';
Jan Glaser
fonte
4
Definir o último caractere para \0não altera o comprimento da sequência. str.length()será impreciso.
JWW
Sim, eu vejo agora. Estamos considerando C ++. Você está correto, isso não muda o comprimento da corda
Jan Glaser