Question

I am trying to search two different strings in a line using strstr.

sBuffer = "This is app test"
s1= strstr (sBuffer, "This");
s2= strstr (sBuffer, "test");
printf("%s\n", s1); //prints - This is app test 
printf("%s\n", s2); //prints - test
if (s1 && s2)
    //do something

Expected output for s1 should be the string "This" but it is printing the entire string for s1.

s2 however is printed correctly.

Any help appreciated.

EDIT: Although all the answers are correct (upvoted all answers), I am accepting dasblinkenlight's answer. This is because I realize checking the boolean condition as shown below would suffice my requirement. Thanks for all the answers.

if ( (strstr (sBuffer, "This")) && (strstr (sBuffer, "test")) )
        //do something
Was it helpful?

Solution 2

The return value of strstr is the pointer to the original, unmodified, string at the point of the match. The reason why the second call displays test is a coincidence: test simply happens to be at the end of the searched string. Had the sBuffer been "This is app test of strstr", the output for the second call would be test of strstr, not simply test.

To fix this, you can change your program like this:

printf("%s\n", s1 ? "This" : "");
printf("%s\n", s2 ? "test" : "");

The reason this works is that you know that the only case when strstr would return a non-null pointer is when it finds the exact match to what you've been searching for. If all you need is a boolean "found/not found" flag, you can simply test s1 and s2 for NULL. You are using this trick already in your final if statement.

OTHER TIPS

You're not understanding what the function does.

It gives you the address in sBuffer ("the haystack") where the search string ("the needle") has been found. It doesn't modify the haystack string, so it won't terminate the sub-string.

You have:

         +---+---+---+---+---+---+---+--+---+---+---+---+---+---+---+---+----+
sBuffer: | T | h | i | s |   | i | s |  | a | p | p |   | t | e | s | t | \0 |
         +---+---+---+---+---+---+---+--+---+---+---+---+---+---+---+---+----+
           ^                                              ^
           |                                              |
           |                                              |
  strstr(sBuffer, "Test")                        strstr(sBuffer, "test")

As you can see, strstr(sBuffer, "Test") will simply return sBuffer, which of course still contains the rest of the characters, it's the same memory buffer.

If you need to extract the sub-string that you found, you must do so yourself. A suitable function to use is strlcpy() if you have it, else strncpy() will work since you know the exact length of the data to copy.

strstr() returns a pointer to the first character of the substring it found. It doesn't NUL-terminate the string after the searched substring, this is the expected and correct behavior.

As to the solution: if you have a non-const string, you can simply modify it so that it's NUL-terminated at the correct position (but then beware of the modifications you made). If not, then make a copy of the substring.

const char *haystack = "abcd efgh ijkl";
const char *needle   = "efgh";

const char *p = strstr(haystack, needle);
if (p) {
    size_t l = strlen(needle);
    char buf[l + 1];
    memcpy(buf, p, l);
    buf[l] = 0;
    printf("%s\n", buf);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top