Как удалить пробелы из строкового объекта в C ++.
Например, как удалить начальные и конечные пробелы из объекта строки ниже.
//Original string: " This is a sample string "
//Desired string: "This is a sample string"
Насколько мне известно, строковый класс не предоставляет никаких методов для удаления начальных и конечных пробелов.
Чтобы усугубить проблему, как расширить это форматирование для обработки лишних пробелов между словами строки. Например,
// Original string: " This is a sample string "
// Desired string: "This is a sample string"
Используя строковые методы, упомянутые в решении, я могу думать о выполнении этих операций в два этапа.
- Удалите начальные и конечные пробелы.
- Используйте find_first_of, find_last_of, find_first_not_of, find_last_not_of и substr несколько раз на границах слова, чтобы получить желаемое форматирование.
site_t
бытьsize_t
? И я думаю, что если у вас есть комментарий, этоno whitespace
означает, что строка пуста или пуста.size_t
опечатку и по очереди в редактировании, но не заметил, что мой комментарий был перевернут, спасибо.Простое удаление начальных, конечных и лишних пробелов из std :: string в одной строке
value = std::regex_replace(value, std::regex("^ +| +$|( ) +"), "$1");
удаление только ведущих пробелов
value.erase(value.begin(), std::find_if(value.begin(), value.end(), std::bind1st(std::not_equal_to<char>(), ' ')));
или
value = std::regex_replace(value, std::regex("^ +"), "");
удаление только конечных пробелов
value.erase(std::find_if(value.rbegin(), value.rend(), std::bind1st(std::not_equal_to<char>(), ' ')).base(), value.end());
или
value = std::regex_replace(value, std::regex(" +$"), "");
удаление только лишних пробелов
value = regex_replace(value, std::regex(" +"), " ");
источник
substr
илиerase
).В настоящее время я использую эти функции:
// 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); }
источник
Алгоритм обрезки строки Boost
#include <boost/algorithm/string/trim.hpp> [...] std::string msg = " some text with spaces "; boost::algorithm::trim(msg);
источник
Это мое решение для удаления начальных и конечных пробелов ...
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);
Результат - «Пламен».
источник
Вот как это сделать:
std::string & trim(std::string & str) { return ltrim(rtrim(str)); }
А вспомогательные функции реализуются как:
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; }
И как только вы все это разместите, вы также можете написать это:
std::string trim_copy(std::string const & str) { auto s = str; return ltrim(rtrim(s)); }
Попробуй это
источник
Пример обрезки начальных и конечных пробелов после предложения Джон-хансона использовать ускорение (удаляет только конечные и ожидающие пробелы):
#include <boost/algorithm/string/trim.hpp> std::string str = " t e s t "; boost::algorithm::trim ( str );
Результаты в
"t e s t"
А также есть
trim_left
приводит к"t e s t "
trim_right
приводит к" t e s t"
источник
/// 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); }
В приведенном выше коде функция isSpace () - это логическая функция, которая сообщает, является ли символ пробелом. Вы можете реализовать эту функцию, чтобы отразить свои потребности, или просто вызовите isspace () из «ctype.h», если хотите. .
источник
Пример обрезки начальных и конечных пробелов
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);
ИЛИ
trimmedSring = aString.substr(aString.find_first_not_of(' '), (aString.find_last_not_of(' ') - aString.find_first_not_of(' ')) + 1);
источник
Использование стандартной библиотеки имеет много преимуществ, но нужно знать о некоторых особых случаях, вызывающих исключения. Например, ни один из ответов не касается случая, когда строка C ++ содержит некоторые символы Unicode. В этом случае, если вы воспользуетесь функцией isspace , будет выдано исключение.
Я использовал следующий код для обрезки строк и некоторых других операций, которые могут пригодиться. Основные преимущества этого кода: он действительно быстрый (быстрее, чем любой код, который я когда-либо тестировал), он использует только стандартную библиотеку и никогда не вызывает исключения:
#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; } }
источник
Это может быть проще всего.
Вы можете использовать
string::find
и,string::rfind
чтобы найти пробелы с обеих сторон и уменьшить строку.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); } }
источник
Я это тестировал, все работает. Таким образом, этот метод processInput просто попросит пользователя ввести что-то. Он вернет строку, в которой нет лишних пробелов внутри, а также лишних пробелов в начале или в конце. Надеюсь это поможет. (также поместите кучу комментариев, чтобы было проще понять).
вы можете увидеть, как это реализовать в main () внизу
#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; }
источник
Зачем усложнять?
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; }
Это работает, даже если ускорение не удалось, без регулярных выражений, без всяких странностей и библиотек.
РЕДАКТИРОВАТЬ: исправление для комментария MM.
источник
В C ++ 17 представлен
std::basic_string_view
шаблон класса, который ссылается на постоянную непрерывную последовательность char-подобных объектов, то есть представление строки. Помимо очень похожего интерфейсаstd::basic_string
, у него есть две дополнительные функции:,remove_prefix()
которая сжимает представление, перемещая его начало вперед; иremove_suffix()
, который сжимает изображение, перемещая его конец назад. Их можно использовать для обрезки начального и конечного пробелов:#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 }; }
Примечание:
std::string_view
ссылка не принадлежит владельцу, поэтому она действительна только до тех пор, пока существует исходная строка.источник
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);
источник
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()); }
источник
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); }
источник
Как насчет начальных и конечных пробелов:
string string_trim(const string& in) { stringstream ss; string out; ss << in; ss >> out; return out; }
Или для предложения:
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); }
источник
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()); }
источник
Нет-
boost
нетregex
, простоstring
библиотека. Это так просто.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); }
источник
На самом деле это более простой случай, чем учет нескольких начальных и конечных символов пробела. Все, что вам нужно сделать, это удалить повторяющиеся соседние символы пробела из всей строки.
Предикат для соседнего пробела будет просто:
auto by_space = [](unsigned char a, unsigned char b) { return std::isspace(a) and std::isspace(b); };
а затем вы можете избавиться от этих повторяющихся соседних символов пробела с
std::unique
помощью идиомы стирания-удаления:// 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 "
Это потенциально оставляет лишний символ пробела спереди и / или сзади. Это можно довольно легко удалить:
if (std::size(s) && std::isspace(s.back())) s.pop_back(); if (std::size(s) && std::isspace(s.front())) s.erase(0, 1);
Вот демо .
источник
Мое решение этой проблемы без использования каких-либо методов STL, а только с использованием собственных методов строки C ++, выглядит следующим образом :
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; }
Я использовал этот метод для передачи проблемы LeetCode Обратные слова в строке
источник
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"); }
источник
А как насчет идиомы « стереть-удалить» ?
std::string s("..."); s.erase( std::remove(s.begin(), s.end(), ' '), s.end() );
Сожалею. Я слишком поздно понял, что вы не хотите удалять все пробелы.
источник