2013-10-02 24 views
10

文字列があり、その中からすべての句読点を削除したいと思います。それ、どうやったら出来るの?私はいくつかの研究を行い、人々がispunct()関数を使っていることを知った(私はそれを試みた)が、私のコードではうまく動作しないようだ。誰もがアイデアを持っていますか?C++文字列から句読点を削除する

#include <string> 

int main() { 

string text = "this. is my string. it's here." 

if (ispunct(text)) 
text.erase(); 

return 0; 
} 
+0

すべての文字を1つずつチェックする必要があります。 –

答えて

-3

私はそれを得た - :アルゴリズムremove_copy_ifを使用して

+0

これは '。'の最初のインスタンスのみを消去しますが、 '。'のすべてのインスタンスではなくすべての句読点を削除しません。 – pippin1289

+0

しかし、forループで動作します – NewFile

+0

あなたは他の人を欺いてはいけません。しかし、それはまたすべての句読点を削除するだけではありません。 – pippin1289

5

ispunctchar値ではない文字列を取ります。

あなたはこれが動作する

for (auto c : string) 
    if (ispunct(c)) text.erase(text.find_first_of(c)); 

のように行うことができますが、それは遅いアルゴリズムです。

+3

text.erase()?本気ですか? –

+1

あなたは私を持っています。 'text.erase()'は動作しません。 –

1

ここでの問題は、ispunct()が、文字列を送信しようとしている間に、1つの引数を文字にしてしまうことです。あなたは、文字のサイズを削除すると

for(size_t i = 0; i<text.length(); ++i) 
    if(ispunct(text[i])) 
    text.erase(i--, 1); 
4
#include <string> 
#include <iostream> 
#include <cctype> 

int main() { 

    std::string text = "this. is my string. it's here."; 

    for (int i = 0, len = text.size(); i < len; i++) 
    { 
     if (ispunct(text[i])) 
     { 
      text.erase(i--, 1); 
      len = text.size(); 
     } 
    } 

    std::cout << text; 
    return 0; 
} 

出力

this is my string its here 

:あなたは、文字列の要素をループし、それがここのような句読点の場合は、各文字を消去するべき文字列が変更されます。削除が発生するたびに更新する必要があります。そして、現在の文字を削除したので、次の文字が現在の文字になります。ループカウンターを減らさないと、句読記号の隣の文字はチェックされません。

string text,result; 
std::remove_copy_if(text.begin(), text.end(),    
         std::back_inserter(result), //Store output   
         std::ptr_fun<int, int>(&std::ispunct) 
         ); 
+0

コンパイルするispunctを取得できません。あなたがしたすべてのヘッダーが含まれています。 – NewFile

+1

」または「」のいずれかを含める必要があります。 – thefourtheye

19

。あなたは新しい文字列として結果を必要とする場合

size_t found = text.find('.'); 
text.erase(found, 1); 
1
#include <iostream> 
#include <string> 
#include <algorithm> 
using namespace std; 

int main() { 
    string str = "this. is my string. it's here."; 

    transform(str.begin(), str.end(), str.begin(), [](char ch) 
    { 
     if(ispunct(ch)) 
      return '\0'; 
     return ch; 
    }); 
} 
8

POWはすでに良い答えを持っています。この回答は、インプレース更新が必要な場合に対処する方法です。

レシピの最初の部分はstd::remove_ifです。これにより、句読点を効率的に削除し、すべての非句読点をそのまま詰めることができます。

std::remove_if (text.begin(), text.end(), ispunct) 

残念ながら、std::remove_ifは文字列を新しいサイズに縮小しません。コンテナ自体にアクセスできないため、できません。したがって、パックされた結果の後に文字列に残ったジャンク文字があります。

これを処理するには、std::remove_ifはまだ必要な文字列の部分を示すイテレータを返します。私は私だけでは間違って持って信じることができない - - eraseのためのイテレータは削除する範囲を示す必要がありますこれは、EDIT [

text.erase (std::remove_if (text.begin(), text.end(), ispunct), text.end()); 

...以下のイディオムにつながる、文字列erase方法で使用することができます、維持する範囲ではありません。]

これは、多くの状況で機能する一般的なテクニックであるため、これをイディオムと呼びます。string以外のタイプは適切なeraseメソッドを提供し、std::remove(と私は今忘れてしまった他のアルゴリズムライブラリ関数かもしれません)は、削除するアイテムのギャップを閉じるが、呼び出し側にコンテナサイズ変更を残すこのアプローチをとっています。

0
#include <iostream> 
#include <string> 

using namespace std; 

int main() 
{ 
    string s;//string is defined here. 

    cout << "Please enter a string with punctuation's: " << endl;//Asking for users input 

    getline(cin, s);//reads in a single string one line at a time 

/* ERROR Check: The loop didn't run at first because a semi-colon was placed at the end 
       of the statement. Remember not to add it for loops. */ 
     for(auto &c : s) //loop checks every character 
     {  
      if (ispunct(c)) //to see if its a punctuation 
       { 
       c=' ';  //if so it replaces it with a blank space.(delete) 
       } 

     } 

     cout << s << endl; 


    system("pause"); 
    return 0; 
    } 
0

あなたは次のようになり、これを行うことができ別の方法:

#include <ctype.h> //needed for ispunct() 
string onlyLetters(string str){ 
    string retStr = ""; 

    for(int i = 0; i < str.length(); i++){ 
     if(!ispunct(str[i])){ 
      retStr += str[i]; 
     } 
    } 
    return retStr; 

これは新しい文字列を作成する代わりに、実際に古い文字列から文字を消去してしまい、それがに少し楽ですより複雑な組み込み関数を使用するよりも頭を包み込むことができます。

0

これを使用すると、テキストファイルokyの文字列のすべての句読点が削除されます。 str.erase(remove_if(str.begin()、str.end()、:: ispunct)、str.end());

関連する問題