Який бажаний спосіб видалити пробіли з рядка в C ++? Я міг би проглянути всі символи та створити нову рядок, але чи є кращий спосіб?
Який бажаний спосіб видалити пробіли з рядка в C ++? Я міг би проглянути всі символи та створити нову рядок, але чи є кращий спосіб?
Відповіді:
Найкраще робити алгоритм remove_if
та простір:
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>
.
Від гамедева
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 разів у невпорядкованих_мапах) Можливо, це через кеш процесора спільного середовища або щось подібне.
Для обрізки використовуйте алгоритми збільшення рядків :
#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()
повертає a size_t
, а не an int
. erase()
бере, а size_type
не ан int
. Функція, ймовірно, не зможе, якщо зустрічаються два послідовних пробіли, оскільки індекс завжди збільшується. Якщо один пробіл буде видалено, цикл буде читати за межі рядка. Ви, ймовірно, повинні видалити цю відповідь, оскільки їй потрібна велика допомога.
Боюся, це найкраще рішення, про яке я можу придумати. Але ви можете скористатися резервом (), щоб заздалегідь виділити мінімум необхідної пам'яті, щоб трохи прискорити роботу. Ви отримаєте новий рядок, який, ймовірно, буде коротшим, але він займе стільки ж пам’яті, але ви уникнете перерозподілу.
EDIT: Залежно від вашої ситуації, це може спричинити менше накладних витрат, ніж поєднання символів навколо.
Спробуйте скористатися різними підходами і побачити, що найкраще підходить для вас: у вас взагалі не виникне проблем із продуктивністю.