Comment supprimer des espaces d'un objet chaîne en C ++.
Par exemple, comment supprimer les espaces de début et de fin de l'objet chaîne ci-dessous.
//Original string: " This is a sample string "
//Desired string: "This is a sample string"
La classe string, pour autant que je sache, ne fournit aucune méthode pour supprimer les espaces de début et de fin.
Pour ajouter au problème, comment étendre cette mise en forme pour traiter les espaces supplémentaires entre les mots de la chaîne. Par exemple,
// Original string: " This is a sample string "
// Desired string: "This is a sample string"
En utilisant les méthodes de chaîne mentionnées dans la solution, je peux penser à faire ces opérations en deux étapes.
- Supprimez les espaces de début et de fin.
- Utilisez find_first_of, find_last_of, find_first_not_of, find_last_not_of et substr , à plusieurs reprises aux limites des mots pour obtenir le formatage souhaité.
site_t
êtresize_t
? Et je pense que là où vous avez le commentaireno whitespace
signifie que la chaîne est entièrement vide ou vide.size_t
faute de frappe et un par un dans l'édition, mais je n'ai pas remarqué que mon commentaire était inversé, merci.Suppression facile des espaces de début, de fin et supplémentaires d'une chaîne std :: string en une ligne
value = std::regex_replace(value, std::regex("^ +| +$|( ) +"), "$1");
suppression uniquement des espaces de début
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("^ +"), "");
suppression uniquement des espaces de fin
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(" +$"), "");
supprimer uniquement les espaces supplémentaires
value = regex_replace(value, std::regex(" +"), " ");
la source
substr
ouerase
).J'utilise actuellement ces fonctions:
// 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); }
la source
Algorithme de coupure de chaîne Boost
#include <boost/algorithm/string/trim.hpp> [...] std::string msg = " some text with spaces "; boost::algorithm::trim(msg);
la source
C'est ma solution pour dépouiller les espaces de début et de fin ...
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);
Le résultat est "Plamen"
la source
Voici comment vous pouvez le faire:
std::string & trim(std::string & str) { return ltrim(rtrim(str)); }
Et les fonctions de support sont implémentées comme:
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; }
Et une fois que tout cela est en place, vous pouvez également écrire ceci:
std::string trim_copy(std::string const & str) { auto s = str; return ltrim(rtrim(s)); }
Essaye ça
la source
Exemple de réduction des espaces de début et de fin suivant la suggestion de Jon-hanson d'utiliser boost (supprime uniquement les espaces de fin et en attente):
#include <boost/algorithm/string/trim.hpp> std::string str = " t e s t "; boost::algorithm::trim ( str );
Résulte en
"t e s t"
Il y a aussi
trim_left
résulte en"t e s t "
trim_right
résulte en" t e s t"
la source
/// 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); }
Dans le code ci-dessus, la fonction isSpace () est une fonction booléenne qui indique si un caractère est un espace blanc, vous pouvez implémenter cette fonction pour refléter vos besoins, ou simplement appeler isspace () depuis "ctype.h" si vous le souhaitez .
la source
Exemple de rognage des espaces de début et de fin
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);
la source
L'utilisation de la bibliothèque standard présente de nombreux avantages, mais il faut être conscient de certains cas particuliers qui provoquent des exceptions. Par exemple, aucune des réponses n'a couvert le cas où une chaîne C ++ a des caractères Unicode. Dans ce cas, si vous utilisez la fonction isspace , une exception sera levée.
J'ai utilisé le code suivant pour couper les chaînes et certaines autres opérations qui pourraient être utiles. Les principaux avantages de ce code sont: il est vraiment rapide (plus rapide que tout code que j'ai jamais testé), il n'utilise que la bibliothèque standard, et il ne provoque jamais d'exception:
#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; } }
la source
Cela pourrait être le plus simple de tous.
Vous pouvez utiliser
string::find
etstring::rfind
pour rechercher des espaces des deux côtés et réduire la chaîne.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); } }
la source
J'ai testé cela, tout fonctionne. Donc, cette méthode processInput demandera simplement à l'utilisateur de taper quelque chose. Elle retournera une chaîne qui n'a pas d'espaces supplémentaires en interne, ni d'espaces supplémentaires au début ou à la fin. J'espère que cela t'aides. (mettez également un tas de commentaires pour le rendre simple à comprendre).
vous pouvez voir comment l'implémenter dans le main () en bas
#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; }
la source
Pourquoi compliquer?
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; }
Cela fonctionne même si boost échouait, pas de regex, pas de trucs bizarres ni de bibliothèques.
EDIT: Correction du commentaire de MM.
la source
C ++ 17 introduit
std::basic_string_view
, un modèle de classe qui fait référence à une séquence contiguë constante d'objets de type char, c'est-à-dire une vue de la chaîne. En plus d'avoir une interface très similaire àstd::basic_string
, il a deux fonctions supplémentairesremove_prefix()
:, qui réduit la vue en faisant avancer son démarrage; etremove_suffix()
, qui rétrécit la vue en déplaçant son extrémité vers l'arrière. Ceux-ci peuvent être utilisés pour réduire les espaces de début et de fin:#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 }; }
Remarque: le
std::string_view
est une référence non propriétaire, il n'est donc valide que tant que la chaîne d'origine existe toujours.la source
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);
la source
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()); }
la source
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); }
la source
Pour les espaces de début et de fin, que diriez-vous:
string string_trim(const string& in) { stringstream ss; string out; ss << in; ss >> out; return out; }
Ou pour une phrase:
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); }
la source
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()); }
la source
Non
boost
, nonregex
, juste lastring
bibliothèque. C'est si simple.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); }
la source
En fait, il s'agit d'un cas plus simple que de comptabiliser plusieurs espaces blancs de début et de fin. Tout ce que vous avez à faire est de supprimer les caractères d'espace blanc adjacents en double de la chaîne entière.
Le prédicat pour l'espace blanc adjacent serait simplement:
auto by_space = [](unsigned char a, unsigned char b) { return std::isspace(a) and std::isspace(b); };
et vous pouvez ensuite vous débarrasser de ces caractères d'espace blanc adjacents en double avec
std::unique
, et l'idiome effacer-supprimer:// 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 "
Cela laisse potentiellement un espace blanc supplémentaire à l'avant et / ou à l'arrière. Cela peut être supprimé assez facilement:
if (std::size(s) && std::isspace(s.back())) s.pop_back(); if (std::size(s) && std::isspace(s.front())) s.erase(0, 1);
Voici une démo .
la source
Ma solution pour ce problème en n'utilisant aucune méthode STL mais uniquement les méthodes propres à la chaîne C ++ est la suivante:
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; }
J'ai utilisé cette méthode pour passer un problème LeetCode Reverse Words in a String
la source
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"); }
la source
Qu'en est-il de l' idiome effacer-supprimer ?
std::string s("..."); s.erase( std::remove(s.begin(), s.end(), ' '), s.end() );
Pardon. J'ai vu trop tard que vous ne vouliez pas supprimer tous les espaces.
la source