在C ++中找到确切的字符串匹配

时间:2012-10-22 21:57:58

标签: c++ string match

以下是我用来检测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)

错误是,程序不会去找“GetSphereSAandVol”,因为它停在“GetSA”。显然,该程序认为“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;

所以,无论如何我可以避免这个?得到我真正想要的东西?非常感谢。

3 个答案:

答案 0 :(得分:4)

你误解了find的工作原理。阅读documentation

条件应该是这样的:

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";
    }
}

答案 1 :(得分:4)

两个错误,一个是你问过的,一个是你没有的。

你的if语句错了。你误解了string::find的工作原理。这是正确的方法

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

如果string::find找不到它要查找的内容,则会返回特殊值string::npos。这是你的if条件应该测试的。

第二个错误,丢失while (!file.eof())循环,完全没必要。

答案 2 :(得分:1)

如果找不到,string::find函数会返回string::npos。否则它返回一个索引。你假设它返回一个布尔值并进行相应的测试。这不起作用,因为string::npos计算为布尔真值(非零)。此外,如果子字符串位于索引零处,则不会传递。

你必须这样做:

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...