Каков предпочтительный способ удаления пробелов из строки в C ++? Я мог бы перебрать все символы и создать новую строку, но есть ли лучший способ?
Каков предпочтительный способ удаления пробелов из строки в C ++? Я мог бы перебрать все символы и создать новую строку, но есть ли лучший способ?
Ответы:
Лучше всего использовать алгоритм remove_if
и isspace:
remove_if(str.begin(), str.end(), isspace);
Теперь сам алгоритм не может изменить контейнер (только изменить значения), поэтому он фактически перетасовывает значения вокруг и возвращает указатель на то, где должен быть конец. Поэтому мы должны вызвать string :: erase, чтобы фактически изменить длину контейнера:
str.erase(remove_if(str.begin(), str.end(), isspace), str.end());
Также следует отметить, что remove_if сделает максимум одну копию данных. Вот пример реализации:
template<typename T, typename P>
T remove_if(T beg, T end, P pred)
{
T dest = beg;
for (T itr = beg;itr != end; ++itr)
if (!pred(*itr))
*(dest++) = *itr;
return dest;
}
erase
позже. Это вернет правильный результат.
isspace
UB для всех наборов символов, кроме оригинального 7-битного ASCII. C99 §7.4 / 1. это не удивляет меня , что это было upvoted в размере 71 голосов , в настоящее время, несмотря на то , очень плохой совет.
isspace
для всех символов, не входящих в ASCII, с практическим выбором подписи по умолчанию для char
. Таким образом, он имеет неопределенное поведение . Я повторяю это, потому что я подозреваю преднамеренную попытку заглушить этот факт в шуме.
std::string::iterator end_pos = std::remove(str.begin(), str.end(), ' ');
str.erase(end_pos, str.end());
<algorithm>
чтобы это работало.
От gamedev
string.erase(std::remove_if(string.begin(), string.end(), std::isspace), string.end());
::isspace
UB.
Можете ли вы использовать Boost String Algo? http://www.boost.org/doc/libs/1_35_0/doc/html/string_algo/usage.html#id1290573
erase_all(str, " ");
remove_if(str.begin(), str.end(), isspace);
упоминал Мэтт Прайс. Я не знаю почему. На самом деле, все вспомогательные элементы, имеющие альтернативы STL, работают медленнее, чем соответствующие gcc (все, что я тестировал). Некоторые из них намного медленнее! (до 5 раз во вставках unordered_map) Возможно, это связано с кэшем ЦП общей среды или чем-то в этом роде.
Для обрезки используйте алгоритмы повышения строки :
#include <boost/algorithm/string.hpp>
using namespace std;
using namespace boost;
// ...
string str1(" hello world! ");
trim(str1); // str1 == "hello world!"
Вы можете использовать это решение для удаления символа:
#include <algorithm>
#include <string>
using namespace std;
str.erase(remove(str.begin(), str.end(), char_to_remove), str.end());
Привет, ты можешь сделать что-то подобное. Эта функция удаляет все пробелы.
string delSpaces(string &str)
{
str.erase(std::remove(str.begin(), str.end(), ' '), str.end());
return str;
}
Я сделал еще одну функцию, которая удаляет все ненужные пробелы.
string delUnnecessary(string &str)
{
int size = str.length();
for(int j = 0; j<=size; j++)
{
for(int i = 0; i <=j; i++)
{
if(str[i] == ' ' && str[i+1] == ' ')
{
str.erase(str.begin() + i);
}
else if(str[0]== ' ')
{
str.erase(str.begin());
}
else if(str[i] == '\0' && str[i-1]== ' ')
{
str.erase(str.end() - 1);
}
}
}
return str;
}
string replaceinString(std::string str, std::string tofind, std::string toreplace)
{
size_t position = 0;
for ( position = str.find(tofind); position != std::string::npos; position = str.find(tofind,position) )
{
str.replace(position ,1, toreplace);
}
return(str);
}
используй это:
string replace = replaceinString(thisstring, " ", "%20");
string replace2 = replaceinString(thisstring, " ", "-");
string replace3 = replaceinString(thisstring, " ", "+");
Если вы хотите сделать это с помощью простого макроса, вот один:
#define REMOVE_SPACES(x) x.erase(std::remove(x.begin(), x.end(), ' '), x.end())
Это предполагает, что вы сделали, #include <string>
конечно.
Назовите это так:
std::string sName = " Example Name ";
REMOVE_SPACES(sName);
printf("%s",sName.c_str()); // requires #include <stdio.h>
Я использовал описанную ниже работу надолго - не уверен насчет ее сложности.
s.erase(std::unique(s.begin(),s.end(),[](char s,char f){return (f==' '||s==' ');}),s.end());
когда вы хотите удалить персонажа ' '
и некоторые, например, -
использовать
s.erase(std::unique(s.begin(),s.end(),[](char s,char f){return ((f==' '||s==' ')||(f=='-'||s=='-'));}),s.end());
аналогично просто увеличьте ||
число символов, которое вы хотите удалить, не 1
но, как уже упоминалось, идиома удаления стирания также выглядит хорошо.
string removeSpaces(string word) {
string newWord;
for (int i = 0; i < word.length(); i++) {
if (word[i] != ' ') {
newWord += word[i];
}
}
return newWord;
}
Этот код в основном берет строку и проходит через все символы в ней. Затем он проверяет, является ли эта строка пробелом, если нет, то символ добавляется в новую строку.
#include <algorithm> using namespace std; int main() { . . s.erase( remove( s.begin(), s.end(), ' ' ), s.end() ); . . }
Ссылка взята с этого форума.
В C ++ 20 вы можете использовать бесплатную функцию std :: erase
std::string str = " Hello World !";
std::erase(str, ' ');
Полный пример:
#include<string>
#include<iostream>
int main() {
std::string str = " Hello World !";
std::erase(str, ' ');
std::cout << "|" << str <<"|";
}
Я печатаю | так что очевидно, что пространство в начале также удаляется.
примечание: при этом удаляется только пробел, а не все другие возможные символы, которые могут считаться пробелами, см. https://en.cppreference.com/w/cpp/string/byte/isspace
Удаляет все пробельные символы, такие как символы табуляции и переноса строк (C ++ 11):
string str = " \n AB cd \t efg\v\n";
str = regex_replace(str,regex("\\s"),"");
string str = "2C F4 32 3C B9 DE";
str.erase(remove(str.begin(),str.end(),' '),str.end());
cout << str << endl;
выход: 2CF4323CB9DE
string removespace(string str)
{
int m = str.length();
int i=0;
while(i<m)
{
while(str[i] == 32)
str.erase(i,1);
i++;
}
}
length()
возвращает, а size_t
не int
. erase()
Посмотри, а size_type
не int
. Функция, вероятно, завершится ошибкой, если встретятся два последовательных пробела, поскольку индекс всегда увеличивается. Если удаляется один пробел, цикл будет читать за пределами строки. Вы, вероятно, должны удалить этот ответ, так как он нуждается в большой помощи.
Боюсь, это лучшее решение, которое я могу придумать. Но вы можете использовать reserve () для предварительного выделения минимально необходимой памяти заранее, чтобы немного ускорить процесс. В итоге вы получите новую строку, которая, вероятно, будет короче, но она займет тот же объем памяти, но вы избежите перераспределения.
РЕДАКТИРОВАТЬ: В зависимости от вашей ситуации, это может потребовать меньше накладных расходов, чем жонглирование символов вокруг.
Вам следует попробовать разные подходы и посмотреть, что лучше для вас: у вас могут вообще не быть проблем с производительностью.