1

I tried to write implementation of the strchr().

char    *ft_strchr(const char *s, int c)
{
(unsigned char)c;
    while (*s)
    {
        if (*s == c)
            return ((char *)s);
        s++;
    }
    if (c == '\0')
        return ((char *)s);
    return (NULL);
}

It works similar in most of cases except this one:

printf("%s\n", strchr("Whats up with you, men", '  up'));

strchr returns

 p with you, men

while me version ft_strchr returns NULL

I'm curious why strchr behaves which way. ' up' converted to unsigned char is 'p' (as int 538998128).

Also I found here different implementation and it behave as strchr even with this data.

char    *ft_strchr(const char *s, int c) {
    while (*s != (unsigned char) c) {
        if (!*s)
            return NULL;
        s++;}
    return (char *)s;
}

Also my version is different I guess they should work similar but they don't. I really interested why?

Thanks in advance.

ivoriik
  • 155
  • 1
  • 11
  • `(unsigned char)c;` on a line by itself doesn't change the type of `c`, it is still an `int`. – Bo Persson Dec 20 '17 at 15:03
  • 1
    You are passing in several characters `' up'` , but treating it as a single character when you do the comparison- this is going to give you issues if you actually intend to search for more than 1 character. You also have to figure out how your compiler treats a character literal containing more than one character `' up` as that is implementation defined - perhaps your compiler only keeps the last `p` or the first space in your multi character literal. – nos Dec 20 '17 at 15:14
  • @nos thanks, I understand that, it was just a test case. The problem was incorrect casting (it should be in expression). – ivoriik Dec 20 '17 at 15:26

1 Answers1

1

In this expression:

*s == c

The term *s, which is of type char, has a range of either -128 to 127 or 0 to 255, depending on whether or not char is signed or unsigned. The value 538998128 of c is outside of this range, so the comparison will never be true.

At the start of the function, you have this line:

(unsigned char)c;

But this does nothing. It casts the value of c to an unsigned char and does nothing with the resulting value. It does not change the value of c.

The other implementation you show casts c to unsigned char and then compares that casted value with *s. That's why the other implementation gives the expected result.

dbush
  • 205,898
  • 23
  • 218
  • 273