How to find out particular word in a string - c++

Problem : I am getting Problem while pass string and find out word in that string.
I have tried below code:
if(string.find("Z03"))
{
// field exists
return true;
}
String :Z030000000057
Here's what I'm trying to do:
if(string.find("Z03"))
{
// field exists
return true;
}
when i pass string in message like ";Z030000000057" then its enter in the loop but when i simply pass "Z030000000057" its go into loop.
Kindly help me for this.

find() returns the index of the first occurrence, or string::npos. Your if is testing if find() returned zero (i.e. first occurrence at beginning of string) or not (i.e. search string occurs later, or not at all).
You are probably looking for...
if ( string.find( "Z03" ) != std::string::npos )
{
// field exists
return true;
}
...which perhaps could be shortened to...
return ( string.find( "Z03" ) != std::string::npos );
...if neither the true nor the false branch do anything else.

Check the documentation on the 'find' method: http://en.cppreference.com/w/cpp/string/basic_string/find
The method returns position of the first character of the found substring or std::string::npos if the substring is not found.
Regarding your examples:
std::string s("Z030000000057");
if(s.find("Z03"))
{
// execution DOES NOT goes here because find returns 0 as found position
}
s = ";Z030000000057";
if(s.find("Z03"))
{
// execution goes here because find returns 1 as found position
}
The correct code would be:
if (s.find("Z03") != std::string::npos)
{
// field exists
}
I recommend using cppreference for further checking standard functions, it's very useful.

Related

Check string for recurrence of specific character

How can I search inside of a string for more than one occurrence of a specific character (in this case a period .)?
I have already tried adapting the answer from this question, but I think I am doing it wrong.
std::string periodCheck = i.convert_to<std::string>();
char subString = '.';
std::size_t pos = periodCheck.find(subString, 0);
int counter;
while(pos != std::string::npos){
counter++;
if(counter > 1){
std::cout << "\nError: Multiple periods\n";
return false;
}
}
The first line simply converts from a Boost multi-precision cpp_dec_float (named i) to a string. I know that this part of the code works, because I use it effectively elsewhere in the program.
I am trying to check if a string contains more than one period. If the string has more than one period in it, the function returns false.
How can I achieve this?
If you find a period, then your next logical step would also be to search again, starting with the next character position.
However, if you review your code, you will not be able to find any place where it is actually searching again. There's no call to find() inside the while loop.
A while loop is not required at all. All you need to do is to call find() a second time, specifying pos+1 as the starting position for the second search, and check the results again. If you find another period, you can call it a wrap. Nothing is to be gained by searching for any remaining periods in the string. You have your answer.
std::size_t pos = periodCheck.find(subString, 0);
if (pos != std::string::npos)
{
pos=periodCheck.find(subString, pos+1);
if (pos != std::string::npos)
return false;
}

std::string::find() not working with std::string as argument

I've run across something that does not make much sense to me when using std::string::find() I'm hoping that someone here is able to spot my error:
std::string testString = "PFAIL";
std::string response = "PFAIL\n";
if( response.find(testString) != std::string::npos )
{
//do something
}
This code NEVER hits the //do something comment for some reason. Any ideas?
Edited: I meant that it never hits the //do something code block, which it should and it does if I express it the following way:
if( response.find( testString.c_str() ) != std::string::npos )
{
// do something
}
Maybe you should consider using straight logic in your if statements:
if( response.find(testString) == std::string::npos )
This logical expression could potentialy confuse you less. If the return value of find equals to std::string::npos then the string in testString variable has not been found in your response string.
Edited: i had the logic in answer the wrong way.
Your condition is the wrong way around from what you appear to be expecting. npos is returned if nothing is found. Since the response clearly contains the test, npos won't be returned and the body of the if will be entered.

Check if string contains other string elements

I am trying to check if string contains elements from different string in specific order.
For example:
large string: thisisstring
small string: hssg
it should return true.
I only figured out how to check if string contains whole other string but not parts.
This is the code that I wrote for checking for now:
if ([largestring rangeOfString:smallstring].location != NSNotFound) {
printf("contains");
}
If there are no more characters to search for from the small string, return true.
Starting from the position after the most recently found character in the large string, do a linear search for the first character from the small string that has not yet been searched for.
If the character was not found, return false.
Start back at 1.
There's no easy way to do this, at least, no built in way that I know of. You would have to iterate through each letter of your small string and find the first letter that matches your large string.
Each time you find a matching letter, you loop to the next smallstring letter, but instead only begin searching at the index after you found the previous letter.
EDIT:
some pseudo code, untested, may have syntax errors:
int foundChar = 0;
for (int l = 0; l < strlen(smallstring); l++)
{
bool found = false;
for (; foundChar < strlen(largestring); foundChar++)
{
if (smallstring[l] == largestring[foundChar])
{
// We break here because we found a matching letter.
// Notice that foundChar is still in scope so we preserve
// its value for the next check.
found = true;
foundChar++; // Increment so the next search starts with the next letter.
break;
}
}
// If we get down here, that means we've searched all of the letters
// and found no match, we can result with a failure to find the match.
if (found == false)
{
return false;
}
}
// If we get here, it means every loop resulted in a valid match.
return true;

string.find() doesn't return -1

The code below is simple. As I know, if string::find() didn't find matches it returns -1. But for some reasons the code below doesn't work. Everytime I run this code I get endless loop. Thank you for help!
#include <string>
#include <iostream>
using namespace std;
int main()
{
string text;
text = "asdasd ijk asdasd";
string toReplace = "ijk";
cout<<text<<endl;
int counter = 0;
while ( text.find(toReplace) != -1)
counter++;
cout<<counter<<endl;
system("pause");
}
Aside from the other answers which are completely correct, I just wanted to add that your while loop would have produced an endless loop anyway. For example:
while(text.find(toReplace) != std::string::npos)
counter++;
will be an endless loop because it will keep trying to find the toReplace string in text and it will always find it (that's because find starts from the beginning of the string each time). This is probably not what you intended.
std::string::find returns std::string::npos if the searched substring is not found, not -1. The exact value of npos is implementation-defined, so use npos, as in
while ( text.find(toReplace) != std::string::npos)
Come to think of it, find couldn't return -1 even if it wanted to because the return type of find is specified to be std::size_t which is an unsigned type.
Additionally, find will always search for the first occurrence of the substring, no matter how many times you call it. If you want to iterate through all the occurrences you should use the overload of find which takes a second parameter - the position from which to start searching.
Whoever told you this or wherever you read it, it lied to you.
If std::string::find fails, it returns std::string::npos, which is not -1.
You should check the documentation about such things, when you're not sure.
So, your while will be something like:
while ( std::string::npos != text.find(toReplace) )
Regarding your comment:
UPDATE: I tried to use while ( text.find(toReplace) != string::npos ) but I still get endless loop :( – user2167403 10 secs ago
You should really learn to read the documentation. Use a variable to store the last result of std::string::find (different from std::string::npos) and use std::string::find's second parameter - pos ( by passing value - last_match_position + 1).
Omitting the second parameter, std::string::find always starts from the beginning of the string, which causes the endless loop.
In the code snippet you provided text variable contains substring "ijk" which is stored in the toReplace variable. As long as in while cycle neither text or toReplace variables are changed, find method will always return not a -1 value which is the condition for while cycle to continue.
As already metioned in other comments you should check not for -1 but for std::string::npos.
It does help to read the manual page (string::npos is the answer).
See http://www.cplusplus.com/reference/string/string/find/

C++: how to judge if the path of the file start with a given path

I have a path, for example, named
/my/path/test/mytestpath
, and I want to judge if it start with a given path, for example
/my/path
The C++17 filesystem library is probably the most robust solution. If C++17 is not available to you, Boost.Filesystem provides an implementation for earlier C++ versions. Try something like:
bool isSubDir(path p, path root)
{
while(p != path()) {
if(p == root) {
return true;
}
p = p.parent_path();
}
return false;
}
Substring the length of the string ( /my/path ) of the original (/my/path/test/mytestpath ) from the beginning.
Check whether two strings are equal.
You can do a string compare of the number of characters in the shorter string.
The fact that the characters match of itself won't mean it is a sub-path because you need to check that the next character in the longer string is a '/'
In C you can use strncmp() which takes a length of characters.
In C++ you can use the same or string compare functions. The find() function will work for this but remember to also check that the next character in the main path is a directory separator.
You could "tokenize" your path but that is likely to not be worth it.
std::string::find() returns the index at which a string was found, with an index of 0 being the start of the string:
std::string path("/my/path/test/mytestpath");
// This will check if 'path' begins with "/my/path/".
//
if (0 == path.find("/my/path/"))
{
// 'path' starts with "/my/path".
}