
Milán Babuškov
Actualmente estoy usando el siguiente código para recortar a la derecha todos los std::strings
en mis programas:
std::string s;
s.erase(s.find_last_not_of(" \n\r\t")+1);
Funciona bien, pero me pregunto si hay algunos casos finales en los que podría fallar.
Por supuesto, las respuestas con alternativas elegantes y también con la solución de ajuste a la izquierda son bienvenidas.

leon timmermans
Utilizando Algoritmos de cadena de Boost sería más fácil:
#include <boost/algorithm/string.hpp>
std::string str("hello world! ");
boost::trim_right(str);
str
es ahora "hello world!"
. También hay trim_left
y trim
que recorta ambos lados.
si agregas _copy
sufijo a cualquiera de los nombres de funciones anteriores, por ejemplo trim_copy
la función devolverá una copia recortada de la cadena en lugar de modificarla a través de una referencia.
si agregas _if
sufijo a cualquiera de los nombres de funciones anteriores, por ejemplo trim_copy_if
puede recortar todos los caracteres que satisfagan su predicado personalizado, a diferencia de solo los espacios en blanco.

Bill el lagarto
Use el siguiente código para recortar a la derecha (finales) los espacios y los caracteres de tabulación de std::strings
(idea):
// trim trailing spaces
size_t endpos = str.find_last_not_of(" \t");
size_t startpos = str.find_first_not_of(" \t");
if( std::string::npos != endpos )
{
str = str.substr( 0, endpos+1 );
str = str.substr( startpos );
}
else {
str.erase(std::remove(std::begin(str), std::end(str), ' '), std::end(str));
}
Y solo para equilibrar las cosas, también incluiré el código de recorte izquierdo (idea):
// trim leading spaces
size_t startpos = str.find_first_not_of(" \t");
if( string::npos != startpos )
{
str = str.substr( startpos );
}
Un poco tarde para la fiesta, pero no importa. Ahora C++11 está aquí, tenemos lambdas y variables automáticas. Entonces mi versión, que también maneja espacios en blanco y cadenas vacías, es:
#include <cctype>
#include <string>
#include <algorithm>
inline std::string trim(const std::string &s)
{
auto wsfront=std::find_if_not(s.begin(),s.end(),[](int c){return std::isspace(c);});
auto wsback=std::find_if_not(s.rbegin(),s.rend(),[](int c){return std::isspace(c);}).base();
return (wsback<=wsfront ? std::string() : std::string(wsfront,wsback));
}
Podríamos hacer un iterador inverso de wsfront
y usar eso como la condición de terminación en el segundo find_if_not
pero eso solo es útil en el caso de una cadena de espacios en blanco, y gcc 4.8 al menos no es lo suficientemente inteligente como para inferir el tipo del iterador inverso (std::string::const_reverse_iterator
) con auto
. No sé qué tan costoso es construir un iterador inverso, así que YMMV aquí. Con esta alteración, el código se ve así:
inline std::string trim(const std::string &s)
{
auto wsfront=std::find_if_not(s.begin(),s.end(),[](int c){return std::isspace(c);});
return std::string(wsfront,std::find_if_not(s.rbegin(),std::string::const_reverse_iterator(wsfront),[](int c){return std::isspace(c);}).base());
}

jeromey adofo
Prueba esto, me funciona.
inline std::string trim(std::string& str)
{
str.erase(str.find_last_not_of(' ')+1); //suffixing spaces
str.erase(0, str.find_first_not_of(' ')); //prefixing spaces
return str;
}