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’를 찾아낸 후 주소값이 반환되었다.

의문점 및 생각해볼점

  1. const char *를 받아서 char *로 리턴?
  2. int c

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형으로 형변환하는 것으로 같은 동작을 하도록 구현했다.