C - <string.h> - strcpy, strncpy, strlcpy 구현하기

skyju·2022년 2월 9일

C

목록 보기
2/5

char *strcpy(char *destination, char * source)
source의 문자열을 destination에 복사하여 저장해줌.
종료 처리
복사를 완료하면 종료문자 '\0'을 붙여 마무리.
반환 값
복사 완료한 destination의 주소, 즉 복사된 문자열이다.

char	*reproduce_strcpy(char *dest, char *src)
{	
	int	i;
	i = 0;
	while (*(src + i))
	{
		*(dest + i) = *(src + i);
		++i;
	}
	*(dest + i) = '\0';
	return (dest);
}

char *strncpy(char *destination, char * source, unsigned int size)
source의 문자열을 size만큼 destination에 복사하여 저장해줌.
종료 처리
source 크기보다 size 크기가 더 클 경우 남은 부분은 '\0'로 채워준다.
만약 source 문자열의 길이가 size와 같거나 더 클 경우 '\0'을 붙여줄 공간이 없어서 붙이지 않는다.
때문에 버퍼 수용성 안에서 원본 보존력은 높지만 오류의 가능성이 존재하여 잘 사용하지 않는다.
반환 값
strcpy와 마찬가지로 복사 완료한 destination의 주소, 즉 복사된 문자열이다.

char	*reproduce_strncpy(char *dest, char *src, unsigned int n)
{
	unsigned int		i;
	i = 0;
	while (*(src + i) && i < n)
	{
		*(dest + i) = *(src + i);
		++i;
	}
	while (i < n)
	{
		*(dest + i) = '\0';
        ++i;
	}
	return (dest);
}

char *strlcpy(char *destination, char * source, unsigned int size)
source의 문자열을 size-1만큼 destination에 복사하여 저장해줌.
종료 처리
size-1만큼만 복사하는 이유는 마지막 자리에 '\0'을 붙여주기 위함이다.
따라서 source가 "abcdef"이고 size가 3인경우에 destination에는 "ab(null)"으로 복사된다.
반환 값
특이하게도 원본 문자열의 길이를 반환한다.

unsigned int	reproduce_strlcpy(char *dest, char *src, unsigned int size)
{
	unsigned int	i;
	unsigned int	src_length;
	i = 0;
	src_length = 0;
	while (*(src + src_length))
		++src_length;
	while (*(src + i) && i < size - 1 && size != 0)
	{
		*(dest + i) = *(src + i);
		++i;
	}
	if (size > 0)
		*(dest + i) = '\0';
	return (src_length);
}

주의 해야 할 사항!
unsinged int와 int값을 계산할 때의 overflow를 잘 고려해야 함
int는 4byte(32 bit)

: -2,147,483,648 ~ 2,147,483,647 의 수를 표현함
unsinged int의 경우 앞의 부호 자리가 빠지기 때문에
: 0 ~ 4,294,967,295 의 수를 표현함

따라서 int = 0 이고 unsigned int = 0일 때,
각 값에 -1 을 해주면 int는 음의 정수 1을 의미하지만
unsigned int는 overflow가 일어나며 (2^32 - 1)을 의미하게 됨!

이 때문에 위의 문제에서 size -1을 할경우 overflow의 문제로 인해 size != 0의 조건을 달아주어야 합니다.

또는 해당 while문을

while (*(src + i) && i + 1 < size)

로 바꾸어 적어주어도 해결 가능합니다.

profile
https://github.com/skyju

0개의 댓글