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)이 클 때

여기서는 s1s2의 문자열이 같으므로 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입니다.

그림 41‑2 strcmp 함수로 문자열 비교

이번에는 사용자가 입력한 두 문자열을 비교해보겠습니다.

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인지, 양수인지, 음수인지 판단하면 됩니다.