Eliminar el último carácter de la cadena C ++

210

¿Cómo puedo eliminar el último carácter de una cadena de C ++?

Lo intenté st = substr(st.length()-1);pero no funcionó.

skazhy
fuente
66
¿Desea una nueva cadena con el último carácter eliminado o la misma cadena sin el último carácter?
Matthieu M.
Para un MFC Visual C ++ CString: CString str=CString("Hello world"); str.Delete(str.GetLength()-1);
sergiol

Respuestas:

193

Para una versión no mutante:

st = myString.substr(0, myString.size()-1);
Matthieu M.
fuente
20
@MatthieuM. Su ejemplo es confuso, creo que la esencia de la pregunta es modificar la cadena original, en su ejemplo no está modificando la cadena original, porque en su ejemplo la cadena original se llama "myString", lo que da lugar a la confusión, en la pregunta es "st". El código debe ser: st = st.substr(0, st.size()-1). Pero todavía no se ve de la manera correcta, creo que es la forma correcta de utilizar la función que se pretende para esta tarea, se llama borrado () y el código es: st.erase(st.size()-1). Esto se llamaría una "versión mutante".
Czarek Tomczak
1
@CzarekTomczak: Entiendo que esto no es exactamente lo que se solicitó, por lo tanto, el descargo de responsabilidad antes de la esencia real.
Matthieu M.
2
@MattPhillips: su solución es específica para C ++ 11 ( pop_backno existía en C ++ 03) y también es una modificación en el lugar (y el OP nunca aclaró si quería en el lugar o no) ... como tal, él tiene una respuesta correcta, pero no la única posible.
Matthieu M.
404

Solución simple si está utilizando C ++ 11. Probablemente O (1) tiempo también:

st.pop_back();
mpgaillard
fuente
49
esto es para c ++ 11!
Amir
1
Como FYI, solo es compatible con GCC 4.7 (por supuesto, junto con el conmutador de compilación -std = c ++ 11)
Shmil The Cat
20
No te olvides de consultar length().
¡Sí, parece demasiado abajo de la página ...!
James Bedford el
1
The behavior is undefined if the string is empty. desde aquí
Raffi
24
if (str.size () > 0)  str.resize (str.size () - 1);

Una alternativa std :: erase es buena, pero me gusta el "- 1" (ya sea basado en un tamaño o en un iterador final), para mí, ayuda a expresar la intención.

Por cierto, ¿realmente no hay std :: string :: pop_back? - parece extraño.

Steve314
fuente
11
No hay std::string::pop_backen C ++ 03; Sin embargo, se ha agregado en C ++ 0x.
James McNellis
OK gracias. Causó un poco de confusión: podría jurar que lo he usado, pero no está allí. Tal vez tengo una biblioteca no estándar en algún compilador en algún lugar (entre VC ++ 2003, VC ++ 2008, MinGW GCC3 MinGW GCC 4 y Linux GCC 4, hay algunas diferencias). Lo más probable es que me esté confundiendo con otros tipos.
Steve314
resize () probablemente no esté destinado para tal uso, es una función relacionada con la memoria, borrar () es para eliminar caracteres.
Czarek Tomczak
3
@Czarek Tomczak: perdón por la respuesta absurdamente tardía, pero resizees una función de cambio de tamaño y no más una función de memoria que cualquier otra cosa que pueda aumentar la memoria necesaria. Por ejemplo, si tiene resizeun tamaño más pequeño, no reducirá la memoria reservada. Creo que está pensando reserve, lo que al menos podría reducir la memoria asignada si se le solicita: vea cambiar el tamaño aquí y reservar aquí .
Steve314
3
if (! str.empty ()) se prefiere sobre el tamaño
ericcurtin
19
buf.erase(buf.size() - 1);

Esto supone que sabe que la cadena no está vacía. Si es así, obtendrás una out_of_rangeexcepción.

RC.
fuente
8
buf [buf.size () - 1] = '\ 0'; no elimina nada, solo cambia el carácter que estaba allí para tener el valor cero. std:; las cadenas pueden contener dichos caracteres.
Neil está en lo correcto. Probablemente debería haber aclarado esto en mi respuesta. La segunda opción cambiará efectivamente el valor del último carácter para que no se imprima, pero la longitud de la cadena seguirá siendo la misma. El uso de borrar en realidad "elimina" el último carácter y cambiará el tamaño de la cadena.
RC.
@RC Se imprimirá, suponiendo que use algo como cout << buf. Cómo aparece dependerá de su plataforma. Y siempre puedes aclarar editando tu respuesta.
¿Qué hay de mejor en size() lugar end()de otra respuesta?
ribamar
17

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

Referencia: std :: string :: erase () prototype 2

no se necesita c ++ 11 o c ++ 0x.

ribamar
fuente
1
Esto puede llevar a una situación extraña: el tamaño de la cadena se ha reducido pero el último carácter no está configurado en '\ 0'.
Deqing
1
@Deqing, ¿puedes dar más detalles de lo que sucede en tal caso?
ribamar
Por ejemplo, si ha string s("abc");, después de borrado parece trabajar: cout<<s; // prints "ab"Sin embargo, el último carácter sigue ahí: cout<<s[2]; // still prints 'c'.
Deqing
1
fácil de arreglar: solostr[str.length()-1] = 0; str.erase(str.end()-1);
taxil
55
@Dequing: su ejemplo no es válido. El borrado reduce el tamaño de la cadena, por lo que el acceso a s[2]es ilegal.
EML
11

Eso es todo lo que necesitas:

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

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

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

  cout<<str2; // output: 12

  return 0;
}
codictorio
fuente
2

Con C ++ 11, ni siquiera necesita la longitud / tamaño. Mientras la cadena no esté vacía, puede hacer lo siguiente:

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

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

str.erase(str.rbegin()) lamentablemente no se compila, ya que reverse_iterator que no se puede convertir a un normal_iterator.

C ++ 11 es tu amigo en este caso.

Cebra
fuente
Este método también tiene problemas, el último carácter no está establecido en '\ 0'.
Deqing
1
¿Alguna razón particular para no hacerlo str.erase(str.end() - 1)?
vallentin
-4

Si la longitud no es cero, también puede

str[str.length() - 1] = '\0';
Jan Glaser
fuente
44
Establecer el último carácter en \0no cambia la longitud de la cadena. str.length()será inexacto
jww
Sí, lo veo ahora. Estamos considerando C ++. Tienes razón, no cambia la longitud de la cadena
Jan Glaser