3

txtファイルから行内の文字列を検出するために使用したコードは次のとおりです。

int main()
{
    std::ifstream file( "C:\\log.txt" );

    std::string line;
    while(!file.eof())
    {
        while( std::getline( file, line ) )   
        {
            int found = -1;
            if((found = line.find("GetSA"))>-1)
                std::cout<<"We found GetSA."<<std::endl;
            else if ((found = line.find("GetVol"))>-1)
                std::cout<<"We found GetVol."<<std::endl;
            else if ((found = line.find("GetSphereSAandVol"))>-1)
                std::cout<<"We found GetSphereSAandVol."<<std::endl;
            else
                std::cout<<"We found nothing!"<<std::endl;

        }
    }
    std::cin.get();
}

そして、ここに私のログファイルがあります:

GetSA (3.000000)

GetVol (3.000000)

GetSphereSAandVol (3.000000)

GetVol (3.000000)

GetSphereSAandVol (3.000000)

GetSA (3.00000)

エラーは、プログラムが「GetSA」で停止するため、「GetSphereSAandVol」を見つけられないことです。明らかに、プログラムは「GetSphereSAandVol」に「GetSA」が含まれていると認識し、次のように実行します。

if(found = line.find("GetSA"))
    std::cout<<"We found GetSA."<<std::endl;

プログラムが実行されることを期待しているので、これはまさに私が望むものではありません:

else if (found = line.find("GetSphereSAandVol"))
    std::cout<<"We found GetSphereSAandVol."<<std::endl;

それで、とにかく私はこれを避けることができますか?本当に欲しいものを手に入れるには?どうもありがとう。

4

3 に答える 3

4

あなたは仕組みを誤解してfindいます。ドキュメントを読んでください。

条件は次のようになります。

if ((found = line.find("xyz")) != line.npos) { /* found "xyz" */ }

プログラム全体を次のように記述します。

int main(int argc, char * argv[])
{
    if (argc != 2) { std::cout << "Bad invocation\n"; return 0; }

    std::ifstream infile(argv[1]);

    if (!infile) { std::cout << "Bad filename '" << argv[1] << "'\n"; return 0; }

    for (std::string line; std::getline(infile, line); )
    {
        int pos;

        if ((pos = line.find("abc")) != line.npos)
        {
            std::cout << "Found line 'abc'\n";
            continue;
        }

        if ((pos = line.find("xyz")) != line.npos)
        {
            std::cout << "Found line 'xyz'\n";
            continue;
        }

        // ...

        std::cout << "Line '" << line << "' did not match anything.\n";
    }
}
于 2012-10-22T22:02:08.733 に答える
4

質問したエラーと質問しなかったエラーの 2 つです。

あなたの if 文が間違っています。あなたは仕組みを誤解してstring::findいます。これが正しい方法です

        if ((found = line.find("GetSA")) != string::npos)
           ...
        else if ((found = line.find("GetVol")) != string::npos)
           ...
        etc.

string::find探しているものが見つからない場合は、特別な値を返しますstring::npos。これは、if 条件がテストする必要があるものです。

2 番目のエラー、while (!file.eof())ループを失います。これはまったく不要です。

于 2012-10-22T22:03:09.657 に答える
1

見つからない場合、関数string::findは戻ります。string::nposそれ以外の場合は、インデックスを返します。ブール値を返し、それに応じてテストしていると想定しています。string::nposブール値の真 (ゼロ以外) に評価されるため、これは機能しません。また、部分文字列がインデックス 0 にある場合、それはパスしません。

代わりにこれを行う必要があります。

if( std::string::npos != (found = line.find("GetSA")) )
   // etc...

個人的には、このように値を設定してテストするスタイルは好きではありませんが、それはあなた次第です。代わりに、単純なヘルパー関数を使用してこれを行うことができます。

bool FindSubString( std::string& str, const char *substr, int& pos )
{
    pos = str.find(substr);
    return pos != std::string::npos;
}

それで:

if( FindSubString( line, "GetSA", found ) )
    // etc...

しかし、あなたの場合、found変数を使用していません。したがって、スタイルについて私が言ったことを無視して、次のことを行うことができます。

if( std::string::npos != line.find("GetSA") )
    // etc...
于 2012-10-22T22:05:29.967 に答える