28

私はソフトウェアを書いていますが、libcurl を使用して Web ページから取得したデータを処理する必要があります。データを取得すると、何らかの理由で余分な改行が含まれています。文字、数字、およびスペースのみを許可する方法を見つける必要があります。そして、改行を含むすべてを削除します。これを行う簡単な方法はありますか?ありがとう。

4

12 に答える 12

47

を受け取り、その文字を削除するか保持するかcharを返す関数を作成します。truefalse

bool my_predicate(char c);

次に、std::remove_ifアルゴリズムを使用して文字列から不要な文字を削除します。

std::string s = "my data";
s.erase(std::remove_if(s.begin(), s.end(), my_predicate), s.end());

要件によっては、独自の述語を記述する代わりに、 のような標準ライブラリの述語の 1 つを使用できる場合がありますstd::isalnum(英数字とスペースを一致させる必要があると述べたので、これは必要なものに正確に適合しない可能性があります)。 .

標準ライブラリ関数を使用する場合は、C 標準ライブラリ ヘッダー内の関数 (使用する関数) と C++ 標準ライブラリ ヘッダー内の関数 (使用しない関数)を区別std::isalnumするために、キャストが必要になります。ロケール固有の文字列処理を実行したい場合を除いて):std::isalnum<cctype>std::isalnum<locale>

s.erase(std::remove_if(s.begin(), s.end(), (int(*)(int))std::isalnum), s.end());

std::stringこれは、任意のシーケンス コンテナー ( 、std::vectorおよびを含む) と同様に機能しますstd::deque。このイディオムは、一般に「消去/削除」イディオムと呼ばれます。このstd::remove_ifアルゴリズムは、通常の配列でも機能します。はstd::remove_if、シーケンスを 1 回だけ通過するため、時間の複雑度は線形になります。

于 2011-06-12T03:12:58.560 に答える
14

以前の使用では、単項引数を渡さstd::isalnumずにコンパイルする必要があるため、ラムダ関数を使用したこのソリューションは正しい答えをカプセル化する必要があります。std::ptr_fun

s.erase(std::remove_if(s.begin(), s.end(), 
[]( auto const& c ) -> bool { return !std::isalnum(c); } ), s.end());
于 2017-08-05T12:08:56.523 に答える
5

eraseを使用している場合は、英数字以外のすべての文字を常にループできますstring

#include <cctype>

size_t i = 0;
size_t len = str.length();
while(i < len){
    if (!isalnum(str[i]) || str[i] == ' '){
        str.erase(i,1);
        len--;
    }else
        i++;
}

Standard Lib を使用している方であれば、おそらくループなしでこれを行うことができます。

バッファのみを使用している場合はchar、ループして、文字が英数字でない場合は、その後のすべての文字を 1 つ後ろにシフトできます (問題のある文字を上書きするため)。

#include <cctype>

size_t buflen = something;
for (size_t i = 0; i < buflen; ++i)
    if (!isalnum(buf[i]) || buf[i] != ' ')
        memcpy(buf[i], buf[i + 1], --buflen - i);
于 2011-06-12T03:08:43.650 に答える
4

James McNellis のコードをもう少し拡張するだけです。彼の機能は、alnum 以外の文字ではなく、alnum 文字を削除することです。

文字列から alnum 以外の文字を削除するには。(alnum = アルファベットまたは数字)

  • 関数を宣言します (渡された char が alnum でない場合、isalnum は 0 を返します)

    bool isNotAlnum(char c) {
        return isalnum(c) == 0;
    }
    
  • そして、これを書きます

    s.erase(remove_if(s.begin(), s.end(), isNotAlnum), s.end());
    

あなたの文字列はalnum文字のみです。

于 2016-12-28T20:23:37.003 に答える
2

remove_copy_if標準アルゴリズムはあなたのケースに非常に適しています。

于 2011-06-12T03:12:11.543 に答える
1

この方法で削除消去アルゴリズムを使用できます-

// Removes all punctuation       
s.erase( std::remove_if(s.begin(), s.end(), &ispunct), s.end());
于 2014-10-16T17:21:04.237 に答える
0

以下は私にとってはうまくいきます。

str.erase(std::remove_if(str.begin(), str.end(), &ispunct), str.end());
str.erase(std::remove_if(str.begin(), str.end(), &isspace), str.end());
于 2016-06-07T11:10:27.153 に答える
-1
void remove_spaces(string data)
{ int i=0,j=0;
    while(i<data.length())
    {
        if (isalpha(data[i]))
        {
        data[i]=data[i];
        i++;
        }
        else
            {
            data.erase(i,1);}
    }
    cout<<data;
}
于 2016-11-28T11:29:05.957 に答える