以下是我用来检测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;
所以,无论如何我可以避免这个?得到我真正想要的东西?非常感谢。
答案 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...