Como remover espaços de um objeto string em C ++.
Por exemplo, como remover espaços iniciais e finais do objeto string abaixo.
//Original string: " This is a sample string "
//Desired string: "This is a sample string"
A classe string, até onde eu sei, não fornece nenhum método para remover espaços à esquerda e à direita.
Para aumentar o problema, como estender essa formatação para processar espaços extras entre palavras da string. Por exemplo,
// Original string: " This is a sample string "
// Desired string: "This is a sample string"
Usando os métodos de string mencionados na solução, posso pensar em fazer essas operações em duas etapas.
- Remova os espaços à esquerda e à direita.
- Use find_first_of, find_last_of, find_first_not_of, find_last_not_of e substr , repetidamente nos limites da palavra para obter a formatação desejada.
site_t
sersize_t
? E eu acho que onde você tem o comentáriono whitespace
significa que a string está toda em branco ou vazia.size_t
erro de digitação e erro na edição, mas não percebi que meu comentário estava invertido, obrigado.Fácil remoção de espaços iniciais, finais e extras de um std :: string em uma linha
value = std::regex_replace(value, std::regex("^ +| +$|( ) +"), "$1");
removendo apenas espaços iniciais
value.erase(value.begin(), std::find_if(value.begin(), value.end(), std::bind1st(std::not_equal_to<char>(), ' ')));
ou
value = std::regex_replace(value, std::regex("^ +"), "");
removendo apenas espaços finais
value.erase(std::find_if(value.rbegin(), value.rend(), std::bind1st(std::not_equal_to<char>(), ' ')).base(), value.end());
ou
value = std::regex_replace(value, std::regex(" +$"), "");
removendo apenas espaços extras
value = regex_replace(value, std::regex(" +"), " ");
fonte
substr
ouerase
).Atualmente, estou usando estas funções:
// trim from left inline std::string& ltrim(std::string& s, const char* t = " \t\n\r\f\v") { s.erase(0, s.find_first_not_of(t)); return s; } // trim from right inline std::string& rtrim(std::string& s, const char* t = " \t\n\r\f\v") { s.erase(s.find_last_not_of(t) + 1); return s; } // trim from left & right inline std::string& trim(std::string& s, const char* t = " \t\n\r\f\v") { return ltrim(rtrim(s, t), t); } // copying versions inline std::string ltrim_copy(std::string s, const char* t = " \t\n\r\f\v") { return ltrim(s, t); } inline std::string rtrim_copy(std::string s, const char* t = " \t\n\r\f\v") { return rtrim(s, t); } inline std::string trim_copy(std::string s, const char* t = " \t\n\r\f\v") { return trim(s, t); }
fonte
Algoritmo de corte de string de reforço
#include <boost/algorithm/string/trim.hpp> [...] std::string msg = " some text with spaces "; boost::algorithm::trim(msg);
fonte
Esta é a minha solução para eliminar os espaços à esquerda e à direita ...
std::string stripString = " Plamen "; while(!stripString.empty() && std::isspace(*stripString.begin())) stripString.erase(stripString.begin()); while(!stripString.empty() && std::isspace(*stripString.rbegin())) stripString.erase(stripString.length()-1);
O resultado é "Plamen"
fonte
Aqui está como você pode fazer isso:
std::string & trim(std::string & str) { return ltrim(rtrim(str)); }
E as funções de suporte são implementadas como:
std::string & ltrim(std::string & str) { auto it2 = std::find_if( str.begin() , str.end() , [](char ch){ return !std::isspace<char>(ch , std::locale::classic() ) ; } ); str.erase( str.begin() , it2); return str; } std::string & rtrim(std::string & str) { auto it1 = std::find_if( str.rbegin() , str.rend() , [](char ch){ return !std::isspace<char>(ch , std::locale::classic() ) ; } ); str.erase( it1.base() , str.end() ); return str; }
E depois de ter tudo isso no lugar, você também pode escrever isto:
std::string trim_copy(std::string const & str) { auto s = str; return ltrim(rtrim(s)); }
Tente isto
fonte
Exemplo para cortar espaços à esquerda e à direita seguindo a sugestão de Jon-Hanson para usar boost (remove apenas espaços à direita e pendentes):
#include <boost/algorithm/string/trim.hpp> std::string str = " t e s t "; boost::algorithm::trim ( str );
Resulta em
"t e s t"
Também há
trim_left
resulta em"t e s t "
trim_right
resulta em" t e s t"
fonte
/// strip a string, remove leading and trailing spaces void strip(const string& in, string& out) { string::const_iterator b = in.begin(), e = in.end(); // skipping leading spaces while (isSpace(*b)){ ++b; } if (b != e){ // skipping trailing spaces while (isSpace(*(e-1))){ --e; } } out.assign(b, e); }
No código acima, a função isSpace () é uma função booleana que diz se um caractere é um espaço em branco, você pode implementar esta função para refletir suas necessidades ou apenas chamar o isspace () de "ctype.h" se desejar .
fonte
Exemplo para cortar espaços à esquerda e à direita
std::string aString(" This is a string to be trimmed "); auto start = aString.find_first_not_of(' '); auto end = aString.find_last_not_of(' '); std::string trimmedString; trimmedString = aString.substr(start, (end - start) + 1);
OU
trimmedSring = aString.substr(aString.find_first_not_of(' '), (aString.find_last_not_of(' ') - aString.find_first_not_of(' ')) + 1);
fonte
Usar a biblioteca padrão tem muitos benefícios, mas deve-se estar ciente de alguns casos especiais que causam exceções. Por exemplo, nenhuma das respostas cobriu o caso em que uma string C ++ tem alguns caracteres Unicode. Nesse caso, se você usar a função isspace , uma exceção será lançada.
Tenho usado o seguinte código para aparar as cordas e algumas outras operações que podem ser úteis. Os principais benefícios desse código são: ele é muito rápido (mais rápido do que qualquer código que já testei), ele usa apenas a biblioteca padrão e nunca causa uma exceção:
#include <string> #include <algorithm> #include <functional> #include <locale> #include <iostream> typedef unsigned char BYTE; std::string strTrim(std::string s, char option = 0) { // convert all whitespace characters to a standard space std::replace_if(s.begin(), s.end(), (std::function<int(BYTE)>)::isspace, ' '); // remove leading and trailing spaces size_t f = s.find_first_not_of(' '); if (f == std::string::npos) return ""; s = s.substr(f, s.find_last_not_of(' ') - f + 1); // remove consecutive spaces s = std::string(s.begin(), std::unique(s.begin(), s.end(), [](BYTE l, BYTE r){ return l == ' ' && r == ' '; })); switch (option) { case 'l': // convert to lowercase std::transform(s.begin(), s.end(), s.begin(), ::tolower); return s; case 'U': // convert to uppercase std::transform(s.begin(), s.end(), s.begin(), ::toupper); return s; case 'n': // remove all spaces s.erase(std::remove(s.begin(), s.end(), ' '), s.end()); return s; default: // just trim return s; } }
fonte
Isso pode ser o mais simples de todos.
Você pode usar
string::find
estring::rfind
para localizar espaços em branco de ambos os lados e reduzir a string.void TrimWord(std::string& word) { if (word.empty()) return; // Trim spaces from left side while (word.find(" ") == 0) { word.erase(0, 1); } // Trim spaces from right side size_t len = word.size(); while (word.rfind(" ") == --len) { word.erase(len, len + 1); } }
fonte
Eu testei isso, tudo funciona. Portanto, este método processInput pedirá apenas que o usuário digite algo. Ele retornará uma string que não possui espaços extras internamente, nem espaços extras no início ou no final. Espero que isto ajude. (também coloque muitos comentários para torná-lo simples de entender).
você pode ver como implementá-lo no main () na parte inferior
#include <string> #include <iostream> string processInput() { char inputChar[256]; string output = ""; int outputLength = 0; bool space = false; // user inputs a string.. well a char array cin.getline(inputChar,256); output = inputChar; string outputToLower = ""; // put characters to lower and reduce spaces for(int i = 0; i < output.length(); i++){ // if it's caps put it to lowercase output[i] = tolower(output[i]); // make sure we do not include tabs or line returns or weird symbol for null entry array thingy if (output[i] != '\t' && output[i] != '\n' && output[i] != 'Ì') { if (space) { // if the previous space was a space but this one is not, then space now is false and add char if (output[i] != ' ') { space = false; // add the char outputToLower+=output[i]; } } else { // if space is false, make it true if the char is a space if (output[i] == ' ') { space = true; } // add the char outputToLower+=output[i]; } } } // trim leading and tailing space string trimmedOutput = ""; for(int i = 0; i < outputToLower.length(); i++){ // if it's the last character and it's not a space, then add it // if it's the first character and it's not a space, then add it // if it's not the first or the last then add it if (i == outputToLower.length() - 1 && outputToLower[i] != ' ' || i == 0 && outputToLower[i] != ' ' || i > 0 && i < outputToLower.length() - 1) { trimmedOutput += outputToLower[i]; } } // return output = trimmedOutput; return output; } int main() { cout << "Username: "; string userName = processInput(); cout << "\nModified Input = " << userName << endl; }
fonte
Por que complicar?
std::string removeSpaces(std::string x){ if(x[0] == ' ') { x.erase(0, 1); return removeSpaces(x); } if(x[x.length() - 1] == ' ') { x.erase(x.length() - 1, x.length()); return removeSpaces(x); } else return x; }
Isso funciona mesmo se o boost falhar, sem regex, sem coisas estranhas ou bibliotecas.
EDIT: Correção para o comentário de MM.
fonte
C ++ 17 introduzido
std::basic_string_view
, um modelo de classe que se refere a uma sequência contígua constante de objetos semelhantes a char, ou seja, uma visualização da string. Além de ter uma interface muito semelhante aostd::basic_string
, tem duas funções adicionaisremove_prefix()
:, que reduz a visualização movendo o início para a frente; eremove_suffix()
, o que reduz a visão movendo sua extremidade para trás. Eles podem ser usados para cortar o espaço inicial e final:#include <string_view> #include <string> std::string_view ltrim(std::string_view str) { const auto pos(str.find_first_not_of(" \t")); str.remove_prefix(pos); return str; } std::string_view rtrim(std::string_view str) { const auto pos(str.find_last_not_of(" \t")); str.remove_suffix(str.length() - pos - 1); return str; } std::string_view trim(std::string_view str) { str = ltrim(str); str = rtrim(str); return str; } int main() { std::string str = " hello world "; auto sv1{ ltrim(str) }; // "hello world " auto sv2{ rtrim(str) }; // " hello world" auto sv3{ trim(str) }; // "hello world" //If you want, you can create std::string objects from std::string_view objects auto s1{ sv1 }; auto s2{ sv2 }; auto s3{ sv3 }; }
Observação: o
std::string_view
é uma referência não proprietária, portanto, só é válido enquanto a string original ainda existir.fonte
Na verdade, este é um caso mais simples do que considerar vários caracteres de espaço em branco à esquerda e à direita. Tudo o que você precisa fazer é remover caracteres de espaço em branco adjacentes duplicados de toda a string.
O predicado para o espaço em branco adjacente seria simplesmente:
auto by_space = [](unsigned char a, unsigned char b) { return std::isspace(a) and std::isspace(b); };
e, em seguida, você pode se livrar desses caracteres de espaço em branco adjacentes duplicados com
std::unique
e o idioma apagar-remover:// s = " This is a sample string " s.erase(std::unique(std::begin(s), std::end(s), by_space), std::end(s)); // s = " This is a sample string "
Isso potencialmente deixa um caractere de espaço em branco extra na frente e / ou atrás. Isso pode ser removido facilmente:
if (std::size(s) && std::isspace(s.back())) s.pop_back(); if (std::size(s) && std::isspace(s.front())) s.erase(0, 1);
Aqui está uma demonstração .
fonte
char *str = (char*) malloc(50 * sizeof(char)); strcpy(str, " some random string (<50 chars) "); while(*str == ' ' || *str == '\t' || *str == '\n') str++; int len = strlen(str); while(len >= 0 && (str[len - 1] == ' ' || str[len - 1] == '\t' || *str == '\n') { *(str + len - 1) = '\0'; len--; } printf(":%s:\n", str);
fonte
void removeSpaces(string& str) { /* remove multiple spaces */ int k=0; for (int j=0; j<str.size(); ++j) { if ( (str[j] != ' ') || (str[j] == ' ' && str[j+1] != ' ' )) { str [k] = str [j]; ++k; } } str.resize(k); /* remove space at the end */ if (str [k-1] == ' ') str.erase(str.end()-1); /* remove space at the begin */ if (str [0] == ' ') str.erase(str.begin()); }
fonte
string trim(const string & sStr) { int nSize = sStr.size(); int nSPos = 0, nEPos = 1, i; for(i = 0; i< nSize; ++i) { if( !isspace( sStr[i] ) ) { nSPos = i ; break; } } for(i = nSize -1 ; i >= 0 ; --i) { if( !isspace( sStr[i] ) ) { nEPos = i; break; } } return string(sStr, nSPos, nEPos - nSPos + 1); }
fonte
Para espaços à esquerda e à direita, que tal:
string string_trim(const string& in) { stringstream ss; string out; ss << in; ss >> out; return out; }
Ou para uma frase:
string trim_words(const string& sentence) { stringstream ss; ss << sentence; string s; string out; while(ss >> s) { out+=(s+' '); } return out.substr(0, out.length()-1); }
fonte
void trimLeftTrailingSpaces(string &input) { input.erase(input.begin(), find_if(input.begin(), input.end(), [](int ch) { return !isspace(ch); })); } void trimRightTrailingSpaces(string &input) { input.erase(find_if(input.rbegin(), input.rend(), [](int ch) { return !isspace(ch); }).base(), input.end()); }
fonte
Não
boost
, nãoregex
, apenas astring
biblioteca. É simples assim.string trim(const string s) { // removes whitespace characters from beginnig and end of string s const int l = (int)s.length(); int a=0, b=l-1; char c; while(a<l && ((c=s.at(a))==' '||c=='\t'||c=='\n'||c=='\v'||c=='\f'||c=='\r'||c=='\0')) a++; while(b>a && ((c=s.at(b))==' '||c=='\t'||c=='\n'||c=='\v'||c=='\f'||c=='\r'||c=='\0')) b--; return s.substr(a, 1+b-a); }
fonte
Minha solução para este problema não usando nenhum método STL, mas apenas os próprios métodos da string C ++ é a seguinte:
void processString(string &s) { if ( s.empty() ) return; //delete leading and trailing spaces of the input string int notSpaceStartPos = 0, notSpaceEndPos = s.length() - 1; while ( s[notSpaceStartPos] == ' ' ) ++notSpaceStartPos; while ( s[notSpaceEndPos] == ' ' ) --notSpaceEndPos; if ( notSpaceStartPos > notSpaceEndPos ) { s = ""; return; } s = s.substr(notSpaceStartPos, notSpaceEndPos - notSpaceStartPos + 1); //reduce multiple spaces between two words to a single space string temp; for ( int i = 0; i < s.length(); i++ ) { if ( i > 0 && s[i] == ' ' && s[i-1] == ' ' ) continue; temp.push_back(s[i]); } s = temp; }
Eu usei este método para passar um problema LeetCode Reverter palavras em uma string
fonte
void TrimWhitespaces(std::wstring& str) { if (str.empty()) return; const std::wstring& whitespace = L" \t"; std::wstring::size_type strBegin = str.find_first_not_of(whitespace); std::wstring::size_type strEnd = str.find_last_not_of(whitespace); if (strBegin != std::wstring::npos || strEnd != std::wstring::npos) { strBegin == std::wstring::npos ? 0 : strBegin; strEnd == std::wstring::npos ? str.size() : 0; const auto strRange = strEnd - strBegin + 1; str.substr(strBegin, strRange).swap(str); } else if (str[0] == ' ' || str[0] == '\t') // handles non-empty spaces-only or tabs-only { str = L""; } } void TrimWhitespacesTest() { std::wstring EmptyStr = L""; std::wstring SpacesOnlyStr = L" "; std::wstring TabsOnlyStr = L" "; std::wstring RightSpacesStr = L"12345 "; std::wstring LeftSpacesStr = L" 12345"; std::wstring NoSpacesStr = L"12345"; TrimWhitespaces(EmptyStr); TrimWhitespaces(SpacesOnlyStr); TrimWhitespaces(TabsOnlyStr); TrimWhitespaces(RightSpacesStr); TrimWhitespaces(LeftSpacesStr); TrimWhitespaces(NoSpacesStr); assert(EmptyStr == L""); assert(SpacesOnlyStr == L""); assert(TabsOnlyStr == L""); assert(RightSpacesStr == L"12345"); assert(LeftSpacesStr == L"12345"); assert(NoSpacesStr == L"12345"); }
fonte
E quanto ao idioma apagar-remover ?
std::string s("..."); s.erase( std::remove(s.begin(), s.end(), ' '), s.end() );
Desculpa. Eu vi tarde demais que você não deseja remover todos os espaços em branco.
fonte