^(코딩캣)^ = @"코딩"하는 고양이;

libc 문자열 조작 함수 정리 (part 01 - strcpy, strncpy)

Language/C & C++
2018. 8. 18. 06:34

libc 문자열 조작 함수 정리


C 언어에서 문자열 처리는 복잡하다. 언어 수준에서 문자열이라는 데이터 형 자체를 지원하지도 않으니, 덧셈 기호(+)나 비교연산자(==)와 같은 기호를 사용하는 직관적인 문자열 연산을 사용할 수 없기 때문이다. C 언어가 문자열 데이터 형을 지원하지 않고, 문자열을 다루는 연산자도 없으니 모든 문자열 연산은 문자열 함수를 통해 이루어진다. C 표준 라이브러리(일명 'libc')에서 str...로 시작하는 함수들이 그것이며, 모두 string.h 헤더(C++은 cstring 헤더)에 정의되어 있으며 본 시리즈를 통해 이들 함수의 사용법을 정리해보고자 한다. 본 시리즈는 cplusplus(http://www.cplusplus.com) 및 MSDN에 나와있는 레퍼런스를 기준으로 하여 작성되었다.

  1. libc 문자열 조작 함수 정리 (part 01 - strcpy, strncpy)
  2. libc 문자열 조작 함수 정리 (part 02 - strcat, strncat)
  3. libc 문자열 조작 함수 정리 (part 03 - strcmp, strncmp)
  4. libc 문자열 조작 함수 정리 (part 04 - strchr, strrchr)
  5. libc 문자열 조작 함수 정리 (part 05 - strstr)
  6. libc 문자열 조작 함수 정리 (part 06 - strtok)
  7. libc 문자열 조작 함수 정리 (part 07 - strspn, strcspn)
  8. libc 문자열 조작 함수 정리 (part 08 - strlen)
  9. libc 문자열 조작 함수 정리 (part 09 - strpbrk)
  10. libc 문자열 조작 함수 정리 (part 10 - strxfrm, strcoll)
  11. libc 문자열 조작 함수 정리 (part 11 - strerror)

Part I. strcpy, strncpy


본 포스팅에서는 문자열 복사copy를 지원하는 함수인 strcpy 계열의 함수에 대해 사용 예를 정리한다.

<Prologue>


strcpy와 strncpy는 둘 다 문자열을 복사하는 함수이다. 복사의 목적은 여러가지가 있겠으나 대체로 원본은 그대로 두어 보존하고, 사본을 하나 만들어서 변조도 하고 수정도 하고 그러기 위함이 대부분이다. C 언어에서 문자열은 끝에 항상 NULL('\0') 문자가 붙는다. 화면으로 보이지는 않지만 분명 메모리상으로는 존재하는 것이 이 문자이다. 문자열의 복사는 이 NULL 문자를 만나면 중단하게 되어 있다.

악의적인 목적으로 문자열에서 NULL 문자를 제거해버리면 컴퓨터는 NULL 문자를 찾을때까지 컴퓨터에 설치된 메모리 전체를 쑤시고 다니면서 자신과 무관한 프로그램이 점유하는 메모리의 내용까지 침범하는데 프로그램을 잘못 짜서 자신의 컴퓨터에서만 일어나면 버그bug지만, 다른 컴퓨터를 그렇게 만든다면 훌륭한 사이버 공격이다. 2003년 1월 25일에 우리나라에서 발생한 1.25 인터넷 대란에서 SQL 서버를 쓰러뜨린 슬래머 웜도 이와 같은 원리이다.

1. strcpy


어쨌든, strcpy는 다음과 같은 원형을 가지며 문자열을 통째로 복사하는 역할을 한다.

char * strcpy(char * destination, const char * source);
destination
사본이 저장될 문자열 버퍼이다.
source
원본 문자열이 담긴 문자열 버퍼이다.

source가 가리키는 주소에서 문자를 하나씩 읽어 destination이 가리키는 주소에 하나씩 베껴적는데 NULL 문자를 만나면 그것까지 복사한 다음에 함수를 종료한다. 함수가 종료될 때 destination이 가리키는 주소를 그대로 반환한다. 다음은 strcpy 함수를 사용하는 예이다.

/* strcpy.c */
#include <stdio.h>
#include <string.h>

int main(int argc, char * argv[])
{
	char str1[64] = "Hello, World!";                        // source string
	char str2[64] = {'\0', };                               // string buffer

	printf("<BEFORE>\n");
	printf("str1 = \"%s\"\n", str1);
	printf("str2 = \"%s\"\n", str2);

	strcpy(str2, str1);                                     // copy string

	printf("<AFTER>\n");
	printf("str1 = \"%s\"\n", str1);
	printf("str2 = \"%s\"\n", str2);

	return 0;
}
[그림 1] strcpy.c 예제 소스 코드
[그림 2] strcpy.c 예제 소스 코드의 실행 결과

1-1. Wide Character 확장 함수 - wcscpy


상기 strcpy는 ASCII 문자열 또는 UTF-8 인코딩의 Unicode 문자열에 대해 사용 가능하다. UTF-16/UTF-32와 같은 Wide Character 문자열의 복사는 아래의 함수를 사용 가능하며, wchar.h, C++에서는 cwchar 헤더를 include한다.

wchar_t * wcscpy (wchar_t * destination, const wchar_t * source);

2. strncpy


strncpy도 문자열 복사이긴 한데 원본 문자열의 글자부터 지정된 수만큼의 문자만을 복사한다. 복사된 문자열의 끝에는 자동으로 NULL이 붙는다. 원형은 다음과 같다.

char * strncpy(char * destination, const char * source, size_t num);
destination
사본이 저장될 메모리이다.
source
원본 문자열이 담긴 메모리이다.
num
처음부터 몇 글자까지만 복사할 것인지 지정합니다.

source가 가리키는 주소에서 문자를 하나씩 읽어 destination이 가리키는 주소에 복사하는데, NULL 문자를 만나면 그것까지만 복사한 다음에 함수를 종료한다. 또는 현재까지 복사된 문자 수가 num에서 지정한 개수와 같아도 함수를 종료한다. 함수가 종료될 때 destination이 가리키는 문자열 버퍼의 주소를 그대로 반환한다. 다음은 strncpy 함수의 사용법이다.

/* strncpy.c */
#include <stdio.h>
#include <string.h>

int main(int argc, char * argv[])
{
	char str1[64] = "Hello, World!";                        // source string
	char str2[64] = {'\0', };                               // string buffer

	printf("<BEFORE>\n");
	printf("str1 = \"%s\"\n", str1);
	printf("str2 = \"%s\"\n", str2);

	strncpy(str2, str1, 5);                                 // copy string

	printf("<AFTER>\n");
	printf("str1 = \"%s\"\n", str1);
	printf("str2 = \"%s\"\n", str2);

	return 0;
}
[그림 3] strncpy.c 예제 소스 코드
[그림 4] strncpy.c 예제 소스 코드의 실행 결과

2-1. Wide Character 확장 함수 - wcsncpy


상기 wcsncpy는 ASCII 문자열 또는 UTF-8 인코딩의 Unicode 문자열에 대해 사용 가능하다. UTF-16/UTF-32와 같은 Wide Character 문자열의 복사는 아래의 함수를 사용 가능하며, wchar.h, C++에서는 cwchar 헤더를 include한다.

wchar_t * wcsncpy (wchar_t * destination, const wchar_t * source, size_t num);

<Epilogue>


본 포스팅을 통해 문자열 복사 함수에 대해 정리해 보았다. 다음 포스팅[libc 문자열 조작 함수 정리 (part 02 - strcat, strncat)]에서는 문자열 끝에 다른 문자열을 이어 붙이는 strcat, strncat 함수에 대해 정리한다.

카테고리 “Language/C & C++”
more...