Reputation: 634
Here is the code I used to detect the string in a line from a txt file:
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();
}
And here is my log file:
GetSA (3.000000)
GetVol (3.000000)
GetSphereSAandVol (3.000000)
GetVol (3.000000)
GetSphereSAandVol (3.000000)
GetSA (3.00000)
The error is, the program will not go to find "GetSphereSAandVol", because it stops at "GetSA". Obviously, the program thinks "GetSphereSAandVol" contains "GetSA", so it will execute:
if(found = line.find("GetSA"))
std::cout<<"We found GetSA."<<std::endl;
which is not exactly what I want, because I am expecting the program to execute:
else if (found = line.find("GetSphereSAandVol"))
std::cout<<"We found GetSphereSAandVol."<<std::endl;
So, anyway I can avoid this? to get what I really want? Thanks a lot.
Upvotes: 4
Views: 15696
Reputation: 477040
You misunderstand how find
works. Read the documentation.
The conditionals should go like this:
if ((found = line.find("xyz")) != line.npos) { /* found "xyz" */ }
I would write your entire program like this:
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";
}
}
Upvotes: 5
Reputation: 63471
The string::find
function returns string::npos
if not found. Otherwise it returns an index. You are assuming it returns a boolean and are testing accordingly. That will not work, because string::npos
evaluates to a boolean truth (non-zero). Also, if the substring is at index zero, that will not pass.
You must instead do this:
if( std::string::npos != (found = line.find("GetSA")) )
// etc...
Personally, I don't like the style of setting a value and testing in this way, but that's up to you. I might do this instead with a simple helper function:
bool FindSubString( std::string& str, const char *substr, int& pos )
{
pos = str.find(substr);
return pos != std::string::npos;
}
Then:
if( FindSubString( line, "GetSA", found ) )
// etc...
But in your case, you're not even using the found
variable. So you can ignore what I've said about style and just do:
if( std::string::npos != line.find("GetSA") )
// etc...
Upvotes: 1
Reputation: 87959
Two errors, one you asked about and one you didn't.
Your if statements are wrong. You misunderstand how string::find
works. This is the correct way
if ((found = line.find("GetSA")) != string::npos)
...
else if ((found = line.find("GetVol")) != string::npos)
...
etc.
If string::find
does not find what it's looking for it returns a special value string::npos
. This is what your if conditions should test for.
Second error, lose the while (!file.eof())
loop, it's completely unnecessary.
Upvotes: 4