Search code examples
cpointersdereferencestring.hstrrchr

How come we have to dereference the pointer returned from strbrk(), but don't have to derefence the pointer returned from strrchr()?


How come we have to dereference the pointer returned from strbrk(), but don't have to derefence the pointer returned from strrchr()?

So I have the code below:

#include <stdio.h>
#include <string.h>


int main(void){
    const char *string1 = "This is a test";
    const char *string2 = "beware";
    printf( "%s\"%s\"\n'%c'%s\n\"%s\"\n", "Of the characters in ", string2,
            *strpbrk( string1, string2 ),
            " appears earliest in ", string1 );
    /// How come for the above example we had to dereference the pointer returned from strbrk()
    ///Below we didn't have to derefence the pointer returned from strrchr() and so we didn't have to
    /// put * in front of the function to dereference it.

    puts("");
    const char *stringg1 = "A zoo has many animals including zebras";
    int c = 'z';
    printf( "%s\n%s'%c'%s\"%s\"\n",
            "The remainder of string1 beginning with the",
            "last occurrence of character ", c,
            " is: ", strrchr(stringg1, c));

}

The output is:

Of the characters in "beware"
'a' appears earliest in 
"This is a test"

The remainder of string1 beginning with the
last occurrence of character 'z' is: "zebras"

My question is why do we have to dereference the pointer in a function like strpbrk() and use *, for it to work properly, but for the bottom bit of code that gets the last occurrence of a string, we don't have to dereference it and use *. In fact, if we dereference strrchr() it causes an error and for the program to crash. From my understanding, strrchr() returns a pointer, so to access the value store in the pointer location, we have to dereference it no?

I read another post and think it may have something to do with the fact that in the top portion, where I use strpbrk() I am only printing a character, whereas in the bottom portion I'm printing a string. If this is the cause, can someone explain why?

I am learning C so please answer using beginner words.


Solution

  • It has nothing to do with strbrk and strchr since both return a string. It has to do with %s vs %c.

    You wanted to print the entire string returned by strbrk, so you used %s and provided (a pointer to) the string.

    You wanted to print the first character of the string returned by strbrk, so you used %c and provided the first character of the string returned by strbrk (*p*( p + 0 )p[0]).

    #include <stdio.h>
    #include <string.h>
    
    int main( void ) {
       const char *s = "The brown fox jumped";
    
       printf( "%c\n", *strpbrk( s, "jf" ) );   // f
       printf( "%s\n", strpbrk( s, "jf" ) );    // fox jumped
    
       printf( "%c\n", *strchr( s, 'e' ) );     // e
       printf( "%s\n", strchr( s, 'e' ) );      // e brown fox jumped
    
       printf( "%c\n", *strrchr( s, 'e' ) );    // e
       printf( "%s\n", strrchr( s, 'e' ) );     // ed
    }
    

    Note the blindly dereferencing the result of these functions is unsafe since they can return NULL. It's also unsafe to blindly provide the value returned by these to %s for the same reason.