0

入力ファイルがあります。いくつかの入力値が含まれています。1 つのオブジェクトの入力が次のような場合:

hss cscf "serving cscf" 32.5 ims 112.134

(注:オブジェクトの変数が複数の単語の文字列を必要とする場合、「....」を使用しました。単一の単語の文字列の場合、引用符はありません)

ifstream を使用してどのように読み取ることができますか? (グーグルで検索しましたが、見つかりませんでした。)

getline を使用して行全体を読み取ろうとしましたが、単一の単語または複数の単語の入力であるかどうかを調べると、再び行き詰まりました!

これについていくつかの提案をしてください。

4

2 に答える 2

1

このプログラムがお役に立てば幸いです

int main()
{
    fstream fstr;
    fstr.open("abc.txt",ios::in);
    string str;
    vector<string> Vec;
    while(getline(fstr,str))
    {
        char* pch;
        bool flag = false;
        string strTmp;
        int counter=0;
        pch = strtok (const_cast<char*>(str.c_str())," ");
        while (pch != NULL)
        {
            //this "is a" sample
            if(pch[0]=='\"')
            {
                flag = true;
                strTmp = strTmp + " " + string(pch).substr(1,strlen(pch)-1);
            }
            else
            {
                if(flag==true)
                {
                    if(pch[strlen(pch)-1]=='\"')
                    {
                        flag=false;
                        strTmp = strTmp + " " + string(pch).substr(0,strlen(pch)-1);
                        Vec.push_back(strTmp);
                    }
                    else
                    {
                        strTmp = strTmp + " " + pch;
                    }
                }
                else
                {
                    Vec.push_back(pch);
                }
            }
            pch = strtok(NULL," ");
        }

    }
    for(auto itr = Vec.begin();itr!=Vec.end();itr++)
        {
            cout<<*itr<<endl;
        }
        getchar();
}

要約を提供するだけです

  1. 各行をstrtok抽出し、スペースを区切り文字として使用して単語を取得します (ここでは、引用符内の単語も複数の単語として扱わずに単一の単語として抽出します。

  2. 抽出された単語ごとに、引用符で始まっているかどうかを確認します。いいえの場合は、ベクトルに追加します。そうでない場合は、一時文字列に追加し、フラグも有効にします。

  3. 次に、各単語が引用符で終わっているかどうか、およびフラグが設定されているかどうかを確認します。両方が満たされる場合は、一時文字列全体をベクトルに追加するか、単語を一時文字列に追加し続けます。

要約すると、これは単語を一時文字列の引用符で囲み、単一の単語をベクトルに直接追加します。引用符が終了すると、一時文字列もベクターに追加されます。

于 2013-08-09T12:50:01.843 に答える
1

ファイルストリームからの入力を解析しようとしており、複数の単語の可能性を扱っているため、汎用サポートと完全にカスタマイズ可能なサポートを使用して処理したい場合、つまり、任意のタイプの入力を解析したい場合は、次に、正規表現が必要になります。

C++11 の正規表現を使用できますが、現時点では gcc でサポートされていません。

したがって、1 つの解決策は、標準の c++98、c++03、および c++0x で動作するはずの boost C++ ライブラリを使用することです。

#include <string>
#include <iostream>
#include <cstdlib>
#include <boost/regex.hpp>
using namespace std;

int main() {
  string text = "hss cscf \"serving\" 32.5 ims 112.134";

  boost::regex e("(\\w+)\\s(\\w+)\\s\"(\\w+\\s?)+\"\\s([0-9]+(\\.[0-9][0-9]?)?)\\s(\\w+)\\s([0-9]+(\\.[0-9][0-9]?)?)");

  boost::sregex_token_iterator iter(text.begin(), text.end(), e, 0);
  boost::sregex_token_iterator end;

  for(; iter != end; ++iter) {
    std::cout << *iter << std::endl;
  }

  return 0;
}

次の方法で、gcc (私は gcc-4.7.2 を使用) を使用してコンパイルできます。

g++ {filename} -std={language version} -I{your boost install location} -L{your boost library location} -o {output filename} {your boost library location}/libboost_regex.a

正規表現が恐ろしく長い理由については、regex を使用して完全な 10 進数の解析をサポートしたい場合、上記は次の文字列に対して正しく機能します。

"hss cscf \"serving\" 32.5 ims 112.134"
"hss cscf \"serving more than one\" 32.5 ims 112.134"
"hss cscf \"serving\" 32 ims 112"

参考文献:

ブースト正規表現: http://www.solarix.ru/for_developers/api/regex-en.html

于 2013-08-09T12:53:04.453 に答える