[libft] ft_strchr
strchr?
#include <string.h>
char *strchr(const char *s, int c);
Linux manpage description
: The strchr() function returns a pointer to the first occurrence of the character c in the string s.
해석 및 부연설명
: 문자열 s에서 문자 c를 탐색하여 가장 처음 발견하는 곳의 위치를 포인터로 반환하는 함수다. 찾지 못한경우 NULL
을 반환한다.
ex)
char str[] = "abcdefgehijk";
char c = 'e';
printf("%s\n", strchr(str, c));
코드 실행 결과
efgehijk
정상적으로 문자 c에 저장된 값인 ‘e’를 찾아낸 후 주소값이 반환되었다.
의문점 및 생각해볼점
strchr
의 문제점
반환값을 char *
형으로 형변환하지 않을 경우 컴파일시 아래와 같은 메세지가 뜨게 된다.
error: return discards ‘const’ qualifier from pointer target type [-Werror=discarded-qualifiers]
리턴값에서 const
를 버리게 된다는 것인데, 생각해보면 strchr
함수 자체가 const char *
형 매개변수를 받아 char *
형을 반환하는 함수다.
그래서 정상적으로 작동시키려면 char *
형으로 바꿔서 반환시켜주어야 하지만… 그럴거면 굳이 왜? 라는 의문이 들었고, 그래서 이것저것 찾아보니 아래와 같은 좋은 글이 있었다.
strchr
에 관한 글
값을 수정하지 않겠다는 const char *
형을 받고서는 수정가능한 char *
형으로 리턴하는데서 문제가 발생할 수 있기 때문에 strchr
이 좋지 않은 함수라는 내용이다.
그래서 C++에서는 아래와 같은 두개의 함수로 나누어 사용한다고 한다.
- const char *strchr ( const char * str, int character );
- char *strchr ( char * str, int character );
일단 C에서는 따로 나뉘어있지 않으니 그냥 쓰는게 맞지만 char *
형으로 리턴한 문자열의 값을 변경하지 않도록 주의해야 할 듯 하다.
매개변수로 int
형을 받는 이유
답이 담긴 스택오버플로우 링크
memset
함수의 경우와 동일했다.
ft_strchr 구현
char *ft_strchr(const char *str, int c)
{
while (1)
{
if (*str == (char)c)
return ((char *)str);
else if (!*str)
return (NULL);
str++;
}
}
원 함수인 strchr
에서는 int
형으로 받아온 c의 값이 char
형의 범위를 벗어나는 경우에는 오버/언더플로우된 값으로 읽어 문자를 비교한다.
따라서 문자 c를 char
형으로 형변환하는 것으로 같은 동작을 하도록 구현했다.