Usuń spacje z std::string w C++

Jaki jest preferowany sposób usuwania spacji z ciągu znaków w C++? Mógłbym przebić wszystkie znaki i zbudować nowy ciąg znaków, ale czy jest lepszy sposób?

19 answers

Najlepszą rzeczą do zrobienia jest użycie algorytmu remove_if i isspace:

remove_if(str.begin(), str.end(), isspace);

Teraz sam algorytm nie może zmienić kontenera(tylko zmodyfikować wartości), więc faktycznie tasuje wartości wokół i zwraca wskaźnik do miejsca, w którym powinien być koniec. Musimy więc wywołać string:: erase, aby zmodyfikować długość kontenera:

str.erase(remove_if(str.begin(), str.end(), isspace), str.end());

Należy również zauważyć, że remove_if zrobi co najwyżej jedną kopię danych. Oto przykładowa implementacja:

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;
}
 271
Author: Matt Price,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-20 20:20:28
std::string::iterator end_pos = std::remove(str.begin(), str.end(), ' ');
str.erase(end_pos, str.end());
 110
Author: Arno,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-17 13:56:21

From gamedev

string.erase(std::remove_if(string.begin(), string.end(), std::isspace), string.end());
 37
Author: rupello,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-01 15:41:26

Czy można użyć Boost String Algo? http://www.boost.org/doc/libs/1_35_0/doc/html/string_algo/usage.html#id1290573

erase_all(str, " "); 
 30
Author: Nemanja Trifunovic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-17 14:36:26

Możesz użyć tego rozwiązania do usunięcia znaku:

#include <algorithm>
#include <string>
using namespace std;

str.erase(remove(str.begin(), str.end(), char_to_remove), str.end());
 17
Author: user2281802,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-16 04:03:15

Do przycinania użyj boost string algorithms :

#include <boost/algorithm/string.hpp>

using namespace std;
using namespace boost;

// ...

string str1(" hello world! ");
trim(str1);      // str1 == "hello world!"
 16
Author: Roman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-10 14:50:35

Cześć, możesz zrobić coś takiego. Ta funkcja usuwa wszystkie spacje.

string delSpaces(string &str) 
{
   str.erase(std::remove(str.begin(), str.end(), ' '), str.end());
   return str;
}

Zrobiłem kolejną funkcję, która usuwa wszystkie niepotrzebne spacje.

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;
}
 12
Author: ddacot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-15 08:58:13
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);
}

Użyj go:

string replace = replaceinString(thisstring, " ", "%20");
string replace2 = replaceinString(thisstring, " ", "-");
string replace3 = replaceinString(thisstring, " ", "+");
 8
Author: SudoBash,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-27 18:23:12

Jeśli chcesz to zrobić za pomocą łatwego makra, oto jeden:

#define REMOVE_SPACES(x) x.erase(std::remove(x.begin(), x.end(), ' '), x.end())

To zakłada, że zrobiłeś #include <string> oczywiście.

Nazwij to tak:

std::string sName = " Example Name ";
REMOVE_SPACES(sName);
printf("%s",sName.c_str()); // requires #include <stdio.h>
 7
Author: Volomike,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-30 21:12:43

Używałem poniższego obejścia przez długi czas - nie jestem pewien jego złożoności.

s.erase(std::unique(s.begin(),s.end(),[](char s,char f){return (f==' '||s==' ');}),s.end());

Gdy chcesz usunąć znak ' ' i niektóre na przykład - Użyj

s.erase(std::unique(s.begin(),s.end(),[](char s,char f){return ((f==' '||s==' ')||(f=='-'||s=='-'));}),s.end());

Podobnie po prostu zwiększ || jeśli liczba znaków, które chcesz usunąć, nie jest 1

Ale jak wspominali inni, idiom erase remove również wydaje się w porządku.

 2
Author: RaGa__M,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-12 08:52:16
string removeSpaces(string word) {
    string newWord;
    for (int i = 0; i < word.length(); i++) {
        if (word[i] != ' ') {
            newWord += word[i];
        }
    }

    return newWord;
}

Ten kod w zasadzie pobiera ciąg znaków i przechodzi przez każdy znak w nim. Następnie sprawdza, czy ten łańcuch jest białą spacją, jeśli nie jest, to znak jest dodawany do nowego łańcucha.

 2
Author: Crisp Apples,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-04-12 00:35:35

W C++20 możesz użyć darmowej funkcji std::erase

std::string str = " Hello World  !";
std::erase(str, ' ');

Pełny przykład:

#include<string>
#include<iostream>

int main() {
    std::string str = " Hello World  !";
    std::erase(str, ' ');
    std::cout << "|" << str <<"|";
}

Drukuję / tak, że jest oczywiste, że przestrzeń na początku jest również usuwana.

Uwaga: usuwa to tylko spację, a nie wszystkie inne możliwe znaki, które można uznać za białe znaki, zobacz https://en.cppreference.com/w/cpp/string/byte/isspace

 2
Author: NoSenseEtAl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-05-24 16:32:58
   #include <algorithm>
   using namespace std;

   int main() {
       .
       .
       s.erase( remove( s.begin(), s.end(), ' ' ), s.end() );
       .
       .
   }

Źródło:

Odniesienie zaczerpnięte z tego forum.

 1
Author: John,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-12-02 08:33:13

Usuwa wszystkie białe znaki , takie jak tabulatory i podziały linii (C++11):

string str = " \n AB cd \t efg\v\n";
str = regex_replace(str,regex("\\s"),"");
 1
Author: AnselmRu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-05 05:44:01
  string str = "2C F4 32 3C B9 DE";
  str.erase(remove(str.begin(),str.end(),' '),str.end());
  cout << str << endl;

Wyjście: 2CF4323CB9DE

 0
Author: Kerim FIRAT,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-11 10:08:22

Tylko dla zabawy, ponieważ inne odpowiedzi są znacznie lepsze niż to.

#include <boost/hana/functional/partial.hpp>
#include <iostream>
#include <range/v3/range/conversion.hpp>
#include <range/v3/view/filter.hpp>
int main() {
    using ranges::to;
    using ranges::views::filter;
    using boost::hana::partial;
    auto const& not_space = partial(std::not_equal_to<>{}, ' ');
    auto const& to_string = to<std::string>;

    std::string input = "2C F4 32 3C B9 DE";
    std::string output = input | filter(not_space) | to_string;
    assert(output == "2CF4323CB9DE");
}
 0
Author: Enlico,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-11-22 12:01:13

Stworzyłem funkcję, która usuwa białe spacje z obu końców łańcucha. Takie jak " Hello World ", zostanie zamienione na "Hello world".

To działa podobnie do strip, lstrip i rstrip funkcje, które są często używane w Pythonie.

string strip(string str) {
    while (str[str.length() - 1] == ' ') {
        str = str.substr(0, str.length() - 1);
    }
    while (str[0] == ' ') {
        str = str.substr(1, str.length() - 1);
    }
    return str;
}

string lstrip(string str) {
    while (str[0] == ' ') {
        str = str.substr(1, str.length() - 1);
    }
    return str;
}

string rstrip(string str) {
    while (str[str.length() - 1] == ' ') {
        str = str.substr(0, str.length() - 1);
    }
    return str;
}
 0
Author: D...,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2021-01-08 10:04:26
string removespace(string str)
{    
    int m = str.length();
    int i=0;
    while(i<m)
    {
        while(str[i] == 32)
        str.erase(i,1);
        i++;
    }    
}
 -1
Author: test c,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-04 19:55:40

Obawiam się, że to najlepsze rozwiązanie, jakie przychodzi mi do głowy. Ale możesz użyć reserve (), aby wstępnie przydzielić minimalną wymaganą pamięć z wyprzedzeniem, aby nieco przyspieszyć. Skończysz z nowym ciągiem, który prawdopodobnie będzie krótszy, ale który zajmuje taką samą ilość pamięci, ale unikniesz realokacji.

EDIT: w zależności od sytuacji, może to wiązać się z mniejszym obciążeniem, niż wygłupianie się postaci.

Powinieneś wypróbować różne podejścia i zobaczyć, co jest dla ciebie najlepsze: ty może nie mieć żadnych problemów z wydajnością.

 -3
Author: Dave Van den Eynde,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-04 19:54:16