문자열 관련 함수 : strlen, strlcpy, strlcat, strchr, strrchr, strnstr, strncmp
dqQQQ
·2023. 11. 25. 12:24
개요
string과 str관련 함수를 알아보겠습니다.
문자와 문자열
strlen
SYNOPSIS
함수 원형
: size_t ft_strlen(const char *s)함수 라이브러리
: #include <string.h>const char *s
: 길이를 셀 문자열리턴값
: 문자열의 길이
DESCRIPTION
파라메터로 들어온 문자열의 길이를 센 다음 리턴해준다.
strlen CODE
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 <string.h>char *dst
: 복사를 할 문자열const char *src
: 복사를 해줄 문자열size_t dstsize
: 복사해줄 개수리턴값
: src의 길이
DESCRIPTION
src 문자열을 널값을 고려하여 dstsize만큼 dst로 복사후에 src의 길이를 리턴
strlcpy CODE
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 <string.h>char *dst
: 이어질 문자열const char *src
: dst뒤에 이을 문자열size_t dstsize
: 이어질 개수리턴값
: dst 기존 길이 + src 길이
DESCRIPTION
src문자열을 널값을 고려하여 dstsize만큼 dst문자열 뒤에 이어 붙인다음
dst 기존 길이와 src 기존 길이를 더한 값을 리턴한다.
strlcat CODE
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 <string.h>const char *s
: 비교를 진행할 문자열int c
: 찾을 문자리턴값
: c를 만났다면 해당 주소값 못 만났다면 널
DESCRIPTION
s문자열에서 c문자를 찾으면 해당 주소값을 리턴하고 함수를 종료하고 끝까지 검사해도 없다면 널값을 리턴
strchr CODE
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 <string.h>const char *s
: 비교를 진행할 문자열int c
: 찾을 문자리턴값
: c를 만났다면 해당 주소값 못 만났다면 널
DESCRIPTION
s문자열을 뒤에서부터 검사하면서 c문자를 찾으면 해당 주소값을 리턴하고 함수를 종료하고 끝까지 검사해도 없다면 널값을 리턴
strrchr CODE
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 <string.h>const char *haystack
: 비교를 진행할 문자열const char *needle
: 찾을 문자열size_t len
: 비교를 진행할 개수리턴값
: needle을 만났다면 해당 주소값 못 만났다면 널
DESCRIPTION
haystack문자열을 검사하면서 needle문자열을 찾으면 해당 주소값을 리턴하고 함수를 종료하고 끝까지 검사해도 없다면 널값을 리턴
strnstr CODE
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 <string.h>const char *s1
: 비교를 진행할 문자열const char *s2
: 비교를 진행할 문자열size_t n
: 비교를 진행할 개수리턴값
: 검사 진행중에 다른 값이 나오면 *s1에서 *s2를 뺀 값, 검사 후에도 안나오면 0반환
DESCRIPTION
s1메모리와 s2메모리를 한 바이트씩 n개만큼 비교해서 다른 값이 나올 경우 *s1에서 *s2를 뺀 값을 리턴하고 종료
만약 n개만큼 비교를 해도 다른 값을 찾지 못했다면 0을 반환한다.
strncmp CODE
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와 같은 원리이다. 다른 점으로는 개수를 지정해준다는 것밖에없다.