libc 문자열 조작 함수 정리
C 언어에서 문자열 처리는 복잡하다. 언어 수준에서 문자열이라는 데이터 형 자체를 지원하지도 않으니, 덧셈 기호(+)나 비교연산자(==)와 같은 기호를 사용하는 직관적인 문자열 연산을 사용할 수 없기 때문이다. C 언어가 문자열 데이터 형을 지원하지 않고, 문자열을 다루는 연산자도 없으니 모든 문자열 연산은 문자열 함수를 통해 이루어진다. C 표준 라이브러리(일명 'libc')에서 str...
로 시작하는 함수들이 그것이며, 모두 string.h
헤더(C++은 cstring
헤더)에 정의되어 있으며 본 시리즈를 통해 이들 함수의 사용법을 정리해보고자 한다. 본 시리즈는 cplusplus(http://www.cplusplus.com) 및 MSDN에 나와있는 레퍼런스를 기준으로 하여 작성되었다.
- libc 문자열 조작 함수 정리 (part 01 - strcpy, strncpy)
- libc 문자열 조작 함수 정리 (part 02 - strcat, strncat)
- libc 문자열 조작 함수 정리 (part 03 - strcmp, strncmp)
- libc 문자열 조작 함수 정리 (part 04 - strchr, strrchr)
- libc 문자열 조작 함수 정리 (part 05 - strstr)
- libc 문자열 조작 함수 정리 (part 06 - strtok)
- libc 문자열 조작 함수 정리 (part 07 - strspn, strcspn)
- libc 문자열 조작 함수 정리 (part 08 - strlen)
- libc 문자열 조작 함수 정리 (part 09 - strpbrk)
- libc 문자열 조작 함수 정리 (part 10 - strxfrm, strcoll)
- libc 문자열 조작 함수 정리 (part 11 - strerror)
Part III. strcmp, strncmp
본 포스팅에서는 문자열 비교compare를 지원하는 함수인 strcmp
계열의 함수에 대해 사용 예를 정리한다.
<Prologue>
정수, 실수 등의 원시 자료형primitive data type에서는 두 변수간의 비교 연산자로 ==
를 사용한다. 그러나 C 언어에서 문자열은 포인터pointer의 일종이기 때문에 ==
연산자를 사용할 경우 두 포인터 간 주소 비교만이 수행되지, 각 주소에 보관된 문자까지는 비교하지 않는다. 포인터가 가리키는 주소를 참조하여 각 문자를 비교함으로써 문자열의 일치 여부를 확인하기 위해서는 strcmp
함수를 사용한다.
1. strcmp
strcmp
함수의 원형은 다음과 같다.
int strncmp(const char * str1, const char * str2);
str1
- 비교를 수행할 첫 번째 문자열이다.
str2
- 비교를 수행할 두 번째 문자열이다.
strcmp
는 두 문자열을 서로 비교한 결과를 반환한다.
일치는 0
, 사전 순서대로 볼 때 str1
이 더 앞쪽에 있다면 음수, str2
가 더 앞쪽에 있다면 양수를 반환한다.
/* strcmp.c */
#include <stdio.h>
#include <string.h>
int main(int argc, char * argv[])
{
char str1[64] = "codingCat"; // the 1st string
char str2[64] = "codingTiger"; // the 2nd string
char str3[64] = "codingCat"; // the 3rd string
int result = 0;
result = strcmp(str1, str3); // "codingCat" = "codingCat"
printf("compare: \"%s\" vs \"%s\" >> %d\n", str1, str3, result);
result = strcmp(str1, str2); // "codingCat" > "codingTiger"
printf("compare: \"%s\" vs \"%s\" >> %d\n", str1, str2, result);
result = strcmp(str2, str3); // "codingTiger" < "codingCat"
printf("compare: \"%s\" vs \"%s\" >> %d\n", str2, str3, result);
return 0;
}
주목할 사항은 strcmp
의 반환 값이다. 앞서 설명한 바와 같이 두 문자열이 같다면 0
을 반환하므로 0인지 아닌지만 확인할 수도 있겠지만, 두 문자열이 서로 다를 경우에 그 우선순위와 두 문자열간 거리 정보를 얻을 수 있다. 예를 들어, 위 코드를 참고하여 strcmp(str1, str2);
를 실행할 경우 str1
과 str2
는 "coding"
까지만 동일하고 그 다음 문자는 각각 'C'
와 'T'
로서 일치하지 않는다. 이 때,
'C'
는 'T'
보다 앞서므로 str1
는 str2
보다 앞선다. 즉, strcmp
는 음수를 반환한다.
strcmp
가 반환할 음수는 구체적으로 두 문자열 사이의 거리이다. 'C'
는 'T'
보다 17번째 앞선 문자이므로(C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T) -17
을 반환한다.
strcmp
의 매개변수를 바꾸었을 경우 또한 원리는 같다. 위 코드를 참고하여 strcmp(str2, str1);
를 실행할 경우 str2
와 str1
는 "coding"
까지만 동일하고 그 다음 문자는 각각 'T'
와 'C'
로서 일치하지 않는다. 이 때,
'T'
는 'C'
보다 앞서므로 str2
는 str1
보다 처진다. 즉, strcmp
는 양수를 반환한다.
strcmp
가 반환할 양수는 구체적으로 두 문자열 사이의 거리이다. 'T'
는 'C'
보다 17번째 뒤에 나오는 문자이므로(C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T) +17
을 반환한다.
요약하면,
strcmp = 0
이면 두 문자열은 일치한다.-
strcmp ≠ 0
이면 두 문자열은 다르다.strcmp > 0
이면 첫 번째 문자열이 두 번째 문자열보다 늦다. 절댓값을 취함으로써 서로 일치하지 않는 최초의 문자 사이의 거리를 알 수 있다.strcmp < 0
이면 첫 번째 문자열이 두 번째 문자열보다 앞선다. 절댓값을 취함으로써 서로 일치하지 않는 최초의 문자 사이의 거리를 알 수 있다.
1-1. Wide Character 확장 함수 - wcscmp
상기 strcmp
는 ASCII 문자열 또는 UTF-8 인코딩의 Unicode 문자열에 대해 사용 가능하다. UTF-16/UTF-32와 같은 Wide Character 문자열의 비교는 아래의 함수를 사용 가능하며, wchar.h
, C++에서는 cwchar
헤더를 include
한다.
int wcscmp (const wchar_t* wcs1, const wchar_t* wcs2);
2. strncmp
strncmp
은 문자열의 일부에 대해서만 비교 연산을 수행하고 나머지 원리는 위에서 정리한 바와 같다.
int strncmp(const char * str1, const char * str2, size_t num);
str1
- 비교를 수행할 첫 번째 문자열이다.
str2
- 비교를 수행할 두 번째 문자열이다.
num
- 비교를 수행할 최대 문자수이다.
마찬가지로 비교 결과를 반환한다. 일치는 0
, 사전 순서대로 볼 때 str1
이 더 앞쪽에 있다면 음수, str2
가 더 앞쪽에 있다면 양수를 반환한다.
/* strncmp.c */
#include <stdio.h>
#include <string.h>
int main(int argc, char * argv[])
{
char str1[] = "codingCat"; // the 1st string
char str2[] = "codingTiger"; // the 2nd string
int result = 0;
result = strncmp(str1, str2, 11); // "codingCat" ! "codingTiger"
printf("strncmp(\"%s\", \"%s\", 11) == %d\n", str1, str2, result);
result = strncmp(str2, str1, 11); // "codingTiger" ! "codingCat"
printf("strncmp(\"%s\", \"%s\", 11) == %d\n", str2, str1, result);
result = strncmp(str1, str2, 6); // "coding" = "coding"
printf("strncmp(\"%s\", \"%s\", 6) == %d\n", str1, str2, result);
result = strncmp(str2, str1, 6); // "coding" = "coding"
printf("strncmp(\"%s\", \"%s\", 6) == %d\n", str2, str1, result);
return 0;
}
2-1. Wide Character 확장 함수 - wcsncmp
상기 strncmp
는 ASCII 문자열 또는 UTF-8 인코딩의 Unicode 문자열에 대해 사용 가능하다. UTF-16/UTF-32와 같은 Wide Character 문자열의 비교는 아래의 함수를 사용 가능하며, wchar.h
, C++에서는 cwchar
헤더를 include
한다.
int wcsncmp (const wchar_t * wcs1, const wchar_t * wcs2, size_t num);
<Epilogue>
본 포스팅을 통해 문자열 비교 함수에 대해 정리해 보았다. 다음 포스팅[libc 문자열 조작 함수 정리 (part 04 - strchr, strrchr)]에서는 문자열에서 특정 문자를 검색하는 strchr
, strrchr
함수에 대해 정리한다.