strlen, strlcpy, strlcat, strchr, strrchr, strnstr, strncmp

개요

string과 str관련 함수를 알아보겠습니다.


문자와 문자열



strlen


SYNOPSIS

  • 함수 원형 : size_t ft_strlen(const char *s)
  • 함수 라이브러리 : #include
  • const char *s : 길이를 셀 문자열
  • 리턴값 : 문자열의 길이


DESCRIPTION

파라메터로 들어온 문자열의 길이를 센 다음 리턴해준다.


strlen CODE

1
2
3
4
5
6
7
8
9
size_t	ft_strlen(const char *s)
{
	size_t	i;

	i = 0;
	while (*(s + i))
		i++;
	return (i);
}

딱히 설명할 부분은 없어보인다.




strlcpy


SYNOPSIS

  • 함수 원형 : size_t ft_strlcpy(char *dst, const char *src, size_t dstsize)
  • 함수 라이브러리 : #include
  • char *dst : 복사를 할 문자열
  • const char *src : 복사를 해줄 문자열
  • size_t dstsize : 복사해줄 개수
  • 리턴값 : src의 길이


DESCRIPTION

src 문자열을 널값을 고려하여 dstsize만큼 dst로 복사후에 src의 길이를 리턴


strlcpy CODE

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
size_t	ft_strlcpy(char *dst, const char *src, size_t dstsize)
{
	size_t	i;
	size_t	tmp;

	tmp = 0;
	i = 0;
	if (!dst || !src)
		return (0);
	while (*(src + tmp))
		tmp++;
	while (i < tmp && i + 1 < dstsize)
	{
		*(dst + i) = *(src + i);
		i++;
	}
	if (dstsize > 0)
		*(dst + i) = 0;
	return (tmp);
}

널값을 고려해주기 때문에 안정성이 좋다.

while에서 i + 1을 해준것은 dstsize가 널값까지 생각한 파라메터이기 때문에 널 값 전까지만 복사를 진행한다.

dstsize가 0이라면 널값도 포함을 안시키게 인자를 넣은 것이므로 dst값을 아예 바꾸지 않고 src길이만 리턴한다.




strlcat


SYNOPSIS

  • 함수 원형 : size_t ft_strlcat(char *dst, const char *src, size_t dstsize)
  • 함수 라이브러리 : #include
  • char *dst : 이어질 문자열
  • const char *src : dst뒤에 이을 문자열
  • size_t dstsize : 이어질 개수
  • 리턴값 : dst 기존 길이 + src 길이


DESCRIPTION

src문자열을 널값을 고려하여 dstsize만큼 dst문자열 뒤에 이어 붙인다음

dst 기존 길이와 src 기존 길이를 더한 값을 리턴한다.


strlcat CODE

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
size_t	ft_strlcat(char *dst, const char *src, size_t dstsize)
{
	size_t i;

	i = 0;
	while (*dst && i < dstsize)
	{
		dst++;
		i++;
	}
	while (*src && i + 1 < dstsize)
	{
		*dst = *src;
		dst++;
		src++;
		i++;
	}
	if (i < dstsize)
		*dst = 0;
	while (*src)
	{
		i++;
		src++;
	}
	return (i);
}

널값을 고려해주기 때문에 안정성이 좋다.

while에서 i + 1을 해준것은 dstsize가 널값까지 생각한 파라메터이기 때문에 널 값 전까지만 복사를 진행한다.

dst의 길이보다 dstsize가 작다면 이어붙일 수가 없다. 간단하게 말하면 dst를 수정하는 일 없이 리턴값만 계산하여 리턴한다.

dstsize가 dst길이보다 큰 경우에는 dst의 널 위치부터 src문자열을 널값을 고려하여 이어붙인다.

만약 다 이어붙였는데도 dstsize보다 작은경우에는 리턴값을 계산해주기 위해서 src의 널값까지 계산해준다.




strchr


SYNOPSIS

  • 함수 원형 : char *ft_strchr(const char *s, int c)
  • 함수 라이브러리 : #include
  • const char *s : 비교를 진행할 문자열
  • int c : 찾을 문자
  • 리턴값 : c를 만났다면 해당 주소값 못 만났다면 널


DESCRIPTION

s문자열에서 c문자를 찾으면 해당 주소값을 리턴하고 함수를 종료하고 끝까지 검사해도 없다면 널값을 리턴


strchr CODE

1
2
3
4
5
6
7
8
9
10
11
12
13
char	*ft_strchr(const char *s, int c)
{
	char	*ret;

	ret = (char *)s;
	while (*ret != c)
	{
		if (!*ret)
			return ((void *)0);
		ret++;
	}
	return (ret);
}

딱히 설명할 부분은 없어보인다.




strrchr


SYNOPSIS

  • 함수 원형 : char *ft_strrchr(const char *s, int c)
  • 함수 라이브러리 : #include
  • const char *s : 비교를 진행할 문자열
  • int c : 찾을 문자
  • 리턴값 : c를 만났다면 해당 주소값 못 만났다면 널


DESCRIPTION

s문자열을 뒤에서부터 검사하면서 c문자를 찾으면 해당 주소값을 리턴하고 함수를 종료하고 끝까지 검사해도 없다면 널값을 리턴


strrchr CODE

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
char	*ft_strrchr(const char *s, int c)
{
	char	*ret;

	ret = (char *)s;
	while (*ret)
		ret++;
	while (*ret != c)
	{
		if (ret == s)
			return ((void *)0);
		ret--;
	}
	return (ret);
}

뒤에서부터 검사하는거 말고는 strchr과 동일하다.




strnstr


SYNOPSIS

  • 함수 원형 : char *ft_strnstr(const char *haystack, const char *needle, size_t len)
  • 함수 라이브러리 : #include
  • const char *haystack : 비교를 진행할 문자열
  • const char *needle : 찾을 문자열
  • size_t len : 비교를 진행할 개수
  • 리턴값 : needle을 만났다면 해당 주소값 못 만났다면 널


DESCRIPTION

haystack문자열을 검사하면서 needle문자열을 찾으면 해당 주소값을 리턴하고 함수를 종료하고 끝까지 검사해도 없다면 널값을 리턴


strnstr CODE

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
char	*ft_strnstr(const char *haystack, const char *needle, size_t len)
{
	size_t	i;
	char	*ret;

	if (!*haystack && !*needle)
		return ((char *)"");
	if (!haystack || !*haystack)
		return ((void *)0);
	ret = (char *)haystack;
	i = ft_strlen(needle);
	if (!needle)
		return (ret);
	while (i <= len)
	{
		if (!ft_memcmp((const char *)ret, needle, i))
			return (ret);
		ret++;
		len--;
	}
	return ((void *)0);
}

strlen을 이용해서 찾을 문자열의 길이를 구한다음

memcmp를 이용해서 비교한다. 찾으면 해당 주소값 리턴하고 끝까지 검사해도 없다면 널값을 리턴하도록한다.




strncmp


SYNOPSIS

  • 함수 원형 : int ft_strncmp(const char *s1, const char *s2, size_t n)
  • 함수 라이브러리 : #include
  • const char *s1 : 비교를 진행할 문자열
  • const char *s2 : 비교를 진행할 문자열
  • size_t n : 비교를 진행할 개수
  • 리턴값 : 검사 진행중에 다른 값이 나오면 *s1에서 *s2를 뺀 값, 검사 후에도 안나오면 0반환


DESCRIPTION

s1메모리와 s2메모리를 한 바이트씩 n개만큼 비교해서 다른 값이 나올 경우 *s1에서 *s2를 뺀 값을 리턴하고 종료

만약 n개만큼 비교를 해도 다른 값을 찾지 못했다면 0을 반환한다.


strncmp CODE

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int	ft_strncmp(const char *s1, const char *s2, size_t n)
{
	unsigned char	c1;
	unsigned char	c2;

	while (n)
	{
		c1 = *s1++;
		c2 = *s2++;
		if (c1 != c2)
			return (c1 - c2);
		if (!c1 || !c2)
			break ;
		n--;
	}
	return (0);
}

strcmp와 같은 원리이다. 다른 점으로는 개수를 지정해준다는 것밖에없다.



3줄 요약

1. 문자와 문자열의 개념을 잘 잡아야한다.

2. 스트링 관련 함수는 string.h가 있을 정도로 유용하고 많이 있다.

3. str*** 함수들을 한번 구현해봄으로써 사용할 때 정확히 알고 사용할것같다. 좋은 경험이다.