C 문자열 처리

C 표준 라이브러리 C 프로그래밍 언어는 표준 라이브러리에 문자열 관련 명령을 구현하는 여러 함수들이 존재한다. 복사, 결합, 토큰화, 검색과 같은 다양한 명령이 지원된다. 문자열의 경우 표준 라이브러리는 문자열이 널 종단된다는 규칙을 사용한다: n개의 문자의 문자열은 n + 1 요소의 배열로 표현되며, 끝은 "NULL" 문자로 끝난다.
# 함수 개요
**string.h**는 C 언어의 표준 라이브러리로, 메모리 블록이나 문자열을 다룰 수 있는 함수들을 포함하고 있다. 유니코드 문자열을 다루려면 wchar.h를 사용한다. {| class="wikitable" ! 함수 !! 설명 |- !colspan=2| 복사 |- | void * **memcpy** ( void * destination, const void * source, size_t num ); ||source가 가리키는 곳부터 num바이트 만큼을 destination이 가리키는 곳에 복사한다. |- | void * **memmove** ( void * destination, const void * source, size_t num ); ||source가 가리키는 곳부터 num바이트 만큼을 destination이 가리키는 곳으로 옮긴다. |- | char * **strcpy** ( char * destination, const char * source ); ||source를 destination에 복사한다. |- | char * **strncpy** ( char * destination, const char * source, size_t num ); ||source에서 destination으로 처음 num개의 문자들을 복사한다. |- !colspan=2| 병합 |- | char * **strcat** ( char * destination, const char * source ); ||source를 destination뒤에 붙인다. |- | char * **strncat** ( char * destination, char * source, size_t num ); ||source에서 destination뒤에 처음 num개의 문자들을 붙인다. |- !colspan=2| 비교 |- | int **memcmp** ( const void * ptr1, const void * ptr2, size_t num ); ||ptr1이 가리키는 처음 num바이트의 데이터와 ptr2가 가리키는 처음 num바이트의 데이터를 비교한다. |- | int **strcmp** ( const char * str1, const char * str2 ); ||str1과 str2를 비교한다. |- | int **strcoll** ( const char * str1, const char * str2 ); ||strcmp와 비슷하지만 LC_COLLATE에 정의되어 있는 방식에 따라 해석 된 후 비교한다. |- | int **strncmp** ( const char * str1, const char * str2, size_t num ); ||str1의 처음 num개의 문자를 str2의 처음 num개의 문자와 비교한다. |- | size_t **strxfrm** ( char * destination, const char * source, size_t num ); ||source를 현재 지역 정보에 따라 문자열을 변환한 후 변환한 문자열의 처음 num개 문자를 destination에 복사한다. |- !colspan=2| 탐색 |- | void * **memchr** ( const void * ptr, int value, size_t num ); ||ptr이 가리키는 메모리의 처음 num바이트 중에서 처음으로 value와 일치하는 값(문자)의 주소를 반환한다. |- | char * **strchr** ( const char * str, int character ); ||str에서 처음으로 character와 일치하는 문자의 주소를 반환한다. |- | size_t **strcspn** ( const char * str1, const char * str2 ); ||str1에서 str2의 문자들을 찾아 일치하는 문자의 처음 위치를 알려줍니다. (예) char str[]="abcdefgh"; int idx; idx=strcspn(str, "cd"); // idx=2 str[2]='c' idx=strcspn(str, "fd"); // idx=3 str[3]='d' idx=strcspn(str, "ecib"); // idx=1 str[1]='b' |- | char * **strpbrk** ( const char * str1, const char * str2 ); ||str1에서 str2에 들어 있는 문자들을 찾아 str2의 문자들 중 str1의 문자들과 첫 번째로 일치하는 문자의 주소를 반환한다. |- | char * **strrchr** ( const char * str, int character ); ||str에서 마지막으로 character와 일치하는 문자의 주소를 반환한다. |- | size_t **strspn** ( const char * str1, const char * str2 ); ||str1에서 str2의 문자들이 아닌 문자의 처음 위치를 알려줍니다. (예) char str[]="abcdefgh"; int idx; idx=strspn(str, "a"); // idx=1 str[1]='b' idx=strspn(str, "abd"); // idx=2 str[2]='c' idx=strspn(str, "cbae"); // idx=3 str[3]='d' |- | char * **strstr** ( const char * str1, const char * str2 ); ||str1에서 str2를 검색하여 가장 먼저 나타나는 곳의 위치를 반환한다. |- | char * **strtok** ( char * str, const char * delimiters ); ||str을 delimiters의 문자들로 분리한다.(원본 문자열 변경) 해당 함수를 사용하면 원본문자열의 delimeters에 해당하는 문자가 NULL로 변경되니 주의해야 한다(원본을 유지하려면 복사본으로 해당 함수를 사용해야 한다) strtok() 함수는 찾는 문자열의 시작위치를 내부에서 static으로 관리하고 1번째 인자가 문자열이면 해당 문자열의 처음 위치로 설정하고 NULL이면 찾은 delimiters의 다음 위치가 설정된다 분리하는 도중에 다른 문자열을 분리하기 위해 해당 함수를 또 사용하면 이미 설정된 문자열의 찾는 위치가 변경되어 원하는 결과를 얻지 못한다(thread-unsafe) strtok_r()을 사용하면 찾는 위치를 주어진 변수로 관리하기에 위의 문제가 없다 (예) char str[]="12&345&789"; char *p, *s; for(p=str;s=strtok(p,"&");p=NULL) printf("%s\n",s); [결과] 12 345 789 |- |char ***strtok_r**(char *str, const char *delim, char **pos); |문자열 str을 주어진 delim문자들로 분리한다(원본문자열 변경) 기능은 strtok()과 동일하며 다른 점은 주어진 3번째 인자로 찾는 위치를 관리하므로 중복 사용해도 문제가 없다(thread-safe) (예) char str[]="12&&345&789"; char *p, *s, *pos; for(p=str;s=strtok_r(p,"&", &pos;);p=NULL) printf("%s\n",s); [결과] 12 345 789 |- |char ***strsep**(char **str, const char *delim); |문자열 str을 delim 문자들로 분리한다(원본문자열 변경) strtok()과 다른 점은 1번째 인자가 포인터의 주소를 넘기는 부분과 delim 문자들로 분리 시 delim 문자가 처음이나 마지막 또는 연속될 경우 strtok()은 무시를 하지만 이 함수는 "" 값으로 분리를 한다 또한 strtok()은 1번째인자를 처음은 해당문자열로 설정하고 2번째부터는 NULL로 설정하여 분리를 하지만 strsep() 함수는 NULL로 설정할 필요가 없다 (예) char str[]="&12&&345&789&"; char *p, *s; for(p=str;s=strsep(&p;,"&");) printf("\n",s); [결과] <> <> <> |- !colspan=2| 기타 |- | void * **memset** ( void * ptr, int value, size_t num ); ||ptr이 가리키는 메모리의 처음 num바이트를 value값(문자)으로 채운다. |- | char * **strerror** ( int errnum ); ||errnum(보통 errno)을 해석한 뒤 그에 해당하는 에러 문자열의 포인터를 반환한다. |- | size_t **strlen** ( const char * str ); ||str의 길이를 반환한다. |- |}
# 변수 · 상수 · 형식
{| class="wikitable" ! 이름 !! 설명 |- !colspan=2| 상수 |- | NULL ||널 포인터의 약어인 상수. 이 상수는 메모리의 어떤 유효한 위치의 개체도 가리키지 않는 포인터 값이다. |- !colspan=2| 형식 정의 |- | size_t ||sizeof 연산자의 결과값을 나타내는 정수(unsigned int)이다. |- |}
# 예제
다음 예제는 Hello World 문자열의 길이를 구해 출력한다. 결과는 11이 출력될 것이다. #include #include int main() { char *string = "Hello World"; printf("%lu\n", (unsigned long)strlen(string)); return 0; }