41.2 문자열 비교하기
strcmp 함수를 사용하면 두 문자열이 같은지 비교할 수 있으며 함수 이름은 문자열을 비교하다(string compare)에서 따왔습니다(string.h 헤더 파일에 선언되어 있습니다).
- strcmp(문자열1, 문자열2);
- int strcmp(const *_Str1, char const *_Str2);
- 문자열 비교 결과를 반환
다음 내용을 소스 코드 편집 창에 입력한 뒤 실행해보세요.
string_compare.c
#include <stdio.h> #include <string.h> // strcmp 함수가 선언된 헤더 파일 int main() { char s1[10] = "Hello"; char *s2 = "Hello"; int ret = strcmp(s1, s2); // 두 문자열이 같은지 문자열 비교 printf("%d\n", ret); // 0: 두 문자열이 같으면 0 return 0; }
실행 결과
0
strcmp(s1, s2);와 같이 strcmp 함수에 비교할 문자열을 넣어주면 결과를 정수로 반환합니다(문자열을 비교할 때 대소문자를 구분함).
- -1: ASCII 코드 기준으로 문자열2(s2)가 클 때
- 0: ASCII 코드 기준으로 두 문자열이 같을 때
- 1: ASCII 코드 기준으로 문자열1(s1)이 클 때
여기서는 s1과 s2의 문자열이 같으므로 0을 반환합니다. 그리고 배열 형태의 문자열, 문자열 포인터 등 문자열의 저장 방식은 문자열 비교에 영향을 주지 않습니다(문자열 포인터에 NULL이 들어가 있다면 에러가 발생합니다).
strcmp 함수는 문자열에서 첫 번째 문자부터 차례대로 비교하며 비교 기준은 각 문자의 ASCII 코드입니다. 다음과 같이 a, b, c로 문자열을 만들면 이해하기 쉽습니다.
string_compare_abc.c
#include <stdio.h> #include <string.h> // strcmp 함수가 선언된 헤더 파일 int main() { // aaa는 ASCII 코드로 97 97 97 // aab는 ASCII 코드로 97 97 98 // aac는 ASCII 코드로 97 97 99 printf("%d\n", strcmp("aaa", "aaa")); // 0: aaa와 aaa는 같으므로 0 printf("%d\n", strcmp("aab", "aaa")); // 1: aab와 aaa 중에서 aab가 크므로 1 printf("%d\n", strcmp("aab", "aac")); // -1: aab와 aac 중에서 aac가 크므로 -1 return 0; }
실행 결과
0 1 -1
"aab"는 ASCII 코드로 97 97 98이고, "aaa"는 97 97 97이라서 "aab"가 큽니다. 즉, 문자열1이 크므로 1을 반환합니다. 그리고 "aab"는 97 97 98이고, "aac"는 97 97 99라서 "aac"가 큽니다. 여기서는 문자열2가 크므로 -1>을 반환합니다.
쉽게 생각해서 앞에 것이 크면 1, 뒤에 것이 크면 -1입니다.
이번에는 사용자가 입력한 두 문자열을 비교해보겠습니다.
string_scanf_compare.c
#define _CRT_SECURE_NO_WARNINGS // scanf 보안 경고로 인한 컴파일 에러 방지 #include <stdio.h> #include <string.h> // strcmp 함수가 선언된 헤더 파일 int main() { char s1[20]; char s2[20]; printf("문자열 두 개를 입력하세요: "); scanf("%s %s", s1, s2); int ret = strcmp(s1, s2); // 입력된 문자열 비교 switch (ret) { case 0: printf("두 문자열이 같음\n"); break; case 1: printf("%s보다 %s가 큼\n", s2, s1); break; case -1: printf("%s보다 %s가 큼\n", s1, s2); break; } return 0; }
소스를 컴파일하여 실행한 뒤 hello world를 입력하고 엔터 키를 누르세요.
실행 결과
문자열 두 개를 입력하세요: hello world (입력) hello보다 world가 큼
scanf 함수를 사용하여 공백으로 구분된 문자열을 입력받은 뒤 배열 두 개에 저장했습니다. 그리고 strcmp 함수로 문자열을 비교한 뒤 반환값은 switch 분기문으로 판단해보았습니다.
한 가지 주의할 점이 있는데 strcmp 함수는 운영체제에 따라서 동작 방식이 조금 다르다는 점입니다. Windows(Visual Studio)에서는 문자열이 다르면 1과 -1을 반환하지만 리눅스와 OS X에서는 ASCII 코드값의 차이를 반환합니다. 그러므로 리눅스와 OS X에서 strcmp의 반환값을 판단할 때는 switch 분기문 대신 if조건문을 사용해야 합니다.
string_scanf_compare_linux_osx.c
#include <stdio.h> #include <string.h> // strcmp 함수가 선언된 헤더 파일 int main() { char s1[20]; char s2[20]; printf("문자열 두 개를 입력하세요: "); scanf("%s %s", s1, s2); int ret = strcmp(s1, s2); // 입력된 문자열 비교 printf("반환값: %d\n", ret); // 리눅스와 OS X에서는 ASCII 코드값의 차이를 반환하므로 // if 조건문으로 판단 if (ret == 0) { printf("두 문자열이 같음\n"); } else if (ret > 0) // 양수일 때 { printf("%s보다 %s가 큼\n", s2, s1); } else if (ret < 0) // 음수일 때 { printf("%s보다 %s가 큼\n", s1, s2); } return 0; }
컴파일 방법은 '부록 1. 리눅스, OS X에서 컴파일하기'를 참조하세요.
실행 방법 및 결과
$ gcc string_scanf_compare_linux_osx.c -o compare $ ./compare 문자열 두 개를 입력하세요: aaf aaa (입력) 반환값: 5 aaa보다 aaf가 큼
다음은 리눅스와 OS X에서 strcmp 함수의 반환값 규칙입니다.
- 문자열1의 ASCII 코드값에서 문자열2의 ASCII 코드값을 뺏을 때 양수가 나오면 문자열1이 크고, 음수가 나오면 문자열2가 큼
- ASCII 코드 기준으로 두 문자열이 같으면 0
"aaf"와 "aaa"를 입력했을 때 반환값이 5가 나왔습니다. 즉, 'f'는 102, 'a'는 97이고 102 - 97은 5이기 때문입니다.
반환값을 판단할 때도 if, else if에 조건식을 지정하여 0인지, 양수인지, 음수인지 판단하면 됩니다.