Thread: What does "strchr()" exactly do...

  1. #1
    Beginning game programmer Petike's Avatar
    Join Date
    Jan 2008
    Posts
    64

    What does "strchr()" exactly do...

    Hi,
    there is a function "strchr()".
    It returns a pointer to the first occurance of given character in string (if there isn't, it returns "NULL").
    But what happen if I will call this function TWICE or MORE?

    For example, we have a program:
    Code:
    #include <stdio.h>
    #include <string.h>
    
    int main(void)
    {
      char str[] = "APPLE";   /* A whatever string */
    
      strchr(str, 'P');   /* First call of function */
      strchr(str, 'P');   /* Second call of function */
    
      return 0;
    }
    I found out that at FIRST call this function returns to me a pointer to the FIRST occurance of 'P', and at SECOND call it returns to me a pointer to the SECOND occurance of 'P'.

    Everywhere is written about this function that it returns a first occurance, but nowhere is written what will happen if I call this function twice or more.


    So if anybody can tell me, what will happen at the second call, if it skip the previous found one and if yes, how does the function know which was the last found character, if it save the last pointer to some "his" memory or what?

    And if it is so, that I have described it above, what would happen if I changed after the first call the value of "str" to the new value:
    Code:
    str == "PEACH"
    so if after that change, the SECOND call of the function returns a pointer to 'P' (the first character of "PEACH"), or if it retuns "NULL" (because the first call returned the second letter of "APPLE" and in "PEACH", the 'P' is the first letter, so if it goes back to the beginning of the word or NEVER)?


    Thanks for answers.

    Petike.

  2. #2
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by Petike View Post
    I found out that at FIRST call this function returns to me a pointer to the FIRST occurance of 'P', and at SECOND call it returns to me a pointer to the SECOND occurance of 'P'.
    I can't believe that's true. What code did you use to make it happen?

  3. #3
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    As far as I know, strchr() should ALWAYS return the first instance of the character.

    The above code modified as this:
    Code:
    #include <stdio.h>
    #include <string.h>
    
    int main(void)
    {
      char str[] = "APPLE";   /* A whatever string */
      char *p, *q;
    
      p = strchr(str, 'P');   /* First call of function */
      q = strchr(str, 'P');   /* Second call of function */
      
      printf("p=%p, q=%p\n", p, q);
    
      return 0;
    }
    Produces:
    p=0022FF61, q=0022FF61

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  4. #4
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    Quote Originally Posted by Petike View Post
    But what happen if I will call this function TWICE or MORE?
    You get the same pointer.
    I found out that at FIRST call this function returns to me a pointer to the FIRST occurance of 'P', and at SECOND call it returns to me a pointer to the SECOND occurance of 'P'.
    Nope.

  5. #5
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >But what happen if I will call this function TWICE or MORE?
    The same thing.

    >I found out that at FIRST call this function returns to me a
    >pointer to the FIRST occurance of 'P', and at SECOND call it
    >returns to me a pointer to the SECOND occurance of 'P'.
    How do you know? You're not saving the result of strchr. I get "PPLE" twice, not "PPLE" and then "PLE" in this program:
    Code:
    #include <stdio.h>
    #include <string.h>
    
    int main ( void )
    {
      char str[] = "APPLE";
    
      puts ( strchr ( str, 'P' ) );
      puts ( strchr ( str, 'P' ) );
    
      return 0;
    }
    >but nowhere is written what will happen if I call this function twice or more
    That's because the function has no internal state. If you call it twice or more with the same arguments, you'll get the same result every time. This is one possible implementation of strchr:
    Code:
    char *strchr ( const char *s, int ch )
    {
      while ( *s != '\0' && *s != ch )
        ++s;
    
      return *s != '\0' ? (char*)s : NULL;
    }
    My best code is written with the delete key.

  6. #6
    Beginning game programmer Petike's Avatar
    Join Date
    Jan 2008
    Posts
    64

    Testing program...

    Quote Originally Posted by brewbuck View Post
    I can't believe that's true. What code did you use to make it happen?
    There is a program:
    Code:
    #include <stdio.h>
    #include <string.h>
    
    int main(void)
    {
      char str[] = "LABEL",   /* A whatever string */
           *p_c;              /* Pointer to a character */
    
      while ((p_c = strchr(str, 'L')) != NULL) {
        *p_c = '*';
      }
    
      puts(str);   /* Printing the final (changed) string */
    
      return 0;
    }
    and the result is:
    Code:
    *ABE*
    so from this results that at first the function returned the first occurance, and then the second one (because at first there was changed the first letter "LABEL" and the the second one "*ABEL" and there arise the word "*ABE*").

    So what now?

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Well modifying the string to overwrite the char you just found (so it's not found again) is something rather different to the back-to-back calls in your first post.

    One again, paraphrasing what you actually tried caused everyone to head off in the wrong direction.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  8. #8
    Beginning game programmer Petike's Avatar
    Join Date
    Jan 2008
    Posts
    64
    Quote Originally Posted by Salem View Post
    Well modifying the string to overwrite the char you just found (so it's not found again) is something rather different to the back-to-back calls in your first post.

    One again, paraphrasing what you actually tried caused everyone to head off in the wrong direction.
    I don't understand exactly what did you want to say me.
    In my second post I wrote a program.
    In that program, I was calling the function "strchr()" twice in the cycle (because in 3-rd-time in the cycle, the function returned "NULL" - and terminated the cycle).

    1. At the first call, there was changed the first 'L' in string.
    2. At the second call, there was changed the second 'L' in string.

    So the function first returned the FIRST occurance of 'L' and then the SECOND occurance of 'L'.

    Am I wrong?

  9. #9
    Beginning game programmer Petike's Avatar
    Join Date
    Jan 2008
    Posts
    64
    Sorrrrrrrrrrrrrrrrrrrry, I was wrong.

    I realized that after the first substitution ('L' to '*'), at the second call the first occurance of 'L' will be the last letter, because there I will have a word "*ABEL", and the first occurance now is the last letter.

    One more sorry for the troubles.

    Thanks for all your answers.

    Petike.

  10. #10
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    > So the function first returned the FIRST occurance of 'L' and then the SECOND occurance of 'L'.

    As demonstrated, the only reason that happens is because you maniplulated your data. strchr does not document the behavior you decribe, so it doesn't happen on it's own.

    Sure you could code a findNext function or something like that very easily (and without haphazardly changing data):
    Code:
    char * findNext( const char * search, int ch )
    {
       char * result = NULL;
       static const char * s;
       
       if( search != NULL )
          s = search;
       
       result = strchr( s, ch );
       if( result != NULL ) 
          s = result + 1;
       return result;
    }
    findNext behaves a bit like strtok does in that it will search from a static buffer until you pass it a new search string. But this has nothing to do with the behavior of the workhorse, strchr.
    Last edited by whiteflags; 01-25-2008 at 11:45 AM.

Popular pages Recent additions subscribe to a feed