2016-09-08 3 views
1

数値と特定の単語を検索するために文字列を分割する方法を見つけようとしています。ここで私はリンゴとオレンジの数を読み込もうとしています。しかし、私がこれを書いたやり方では、 "りんご"や "オレンジ"という言葉の前後に句読点があると、それはカウントされません。たとえば、テキストファイルを考えてみましょう。デリミタを使用したC++のintと文字列の解析

3りんご2オレンジ
3りんご。 2オレンジ。
(3リンゴ2オレンジ)

このプログラムは、句読点がないため、最初の行のみを集計します。私は誰かが私にこの問題に対するよりよいアプローチを示すことができることを望んでいました。それはここに必要なのはすべてのことのように私には見えます

#include <iostream> 
#include <string> 
#include <fstream> 
#include<sstream> 
using namespace std; 

void readString(string line, int& a, int& o); 
//splits the string up into substrings 

void assignValue(string str, int& a, int& o, int v); 
// takes the word following the value and decides whether to assign it to  apples, oranges, or neither 

int main() 
{ 
    ifstream inStream; 
    inStream.open(name_of_file); 

    int apples = 0, oranges = 0; 
    string line; 

    while (!(inStream.eof())) 
    { 
     getline(inStream, line); 
     readString(line, apples, oranges); 
    } 

    cout << "Apples:" << apples << endl; 
    cout << "Oranges" << oranges << endl; 

    inStream.close(); 

    system("pause"); 
    return 0; 
} 

    void readString(string l, int& a, int& o) 
    { 
     stringstream ss(l); 
     string word; 
     int value = 0; 

     while (ss >> word) 
     { 
      istringstream convert(word 
      if (convert >> value)       
      { 
       ss >> word;       
       assignValue(word, a, o, value);    
      } 
     } 
    } 

    void assignValue(string str, int& a, int& o, int v) 
    { 
     if (str == "apples") 
     { 
      a += v; 
     } 
     if (str == "oranges") 
     { 
      o += v; 
     } 
    } 
+1

を脇に置いてください。 'while(!inStream.eof()))'の代わりに、 'if(inStream >> line)'だけを使うべきです。 'eof'はエラーをチェックせず、ファイルの終わりだけをチェックします。 [ここ](http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong)を参照してください。 –

答えて

0

はうまく空白で区切られた単語に文字列を切り刻むなり、既存の解析コードを、実行する前に、スペースに文字列内の任意の句読点を交換することです。

「句読点」を「文字または数字以外のもの」と定義しましょう。

それはそのstd::stringstreamを構築する前に、あなたはreadString()std::replace_if()を使用することができます。

std::replace_if(l.begin(), l.end(), [](char c) { return !isalnum(c) }, ' '); 

それとも、あなたは少し明示的になりたい場合:

for (char &c:l) 
{ 
    if (!isalnum(c)) 
     c=' '; 
} 

今、すべての句読点であること現在はスペースで置き換えられているので、そこにある既存のコードはこの後にきちんと整理する必要があります。

数値が小数点以下になる可能性があります。あなたがそれらをintと宣言して以来、これは当てはまりません。しかし、 "4.5リンゴ"のようなものを入力として受け入れる必要がある場合は、もちろん、このコードは期間をスペースで置き換えるため、追加作業が必要になります。しかし、それはちょうど心のノート、心に留めておくことです。