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)

错误是,程序不会去寻找“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;

那么,无论如何我可以避免这种情况吗?得到我真正想要的东西?非常感谢。

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

两个错误,一个是您询问的,一个是您没有询问的。

你的 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())循环,完全没有必要。

于 2012-10-22T22:03:09.657 回答
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...
于 2012-10-22T22:05:29.967 回答