본문 바로가기

문자열 비교 함수

1. 문자열 비교 함수

 

#include <string.h>

 

int strcmp(const char * s1, const char * s2);

int strncmp(const char * s1, const char * s2, size_t n);

 

문자열의 내용이 같으면 0, 아니면 0이 아닌 값을 반환한다.

 strncmp  함수는  n 바이트만 비교한다.

 s1 이 더 크면 양수가,  s2 가 더 크면 음수가,  s1 과  s2 의 모든 문자가 같으면 0이 반환된다.

여기서 크고 작음은 아스키 코드 값을 기준으로 결정된다.

 

그런데 문자열을 비교하는 데 굳이 함수를 써야 하는 걸까?

물론 써야 하니까 소개하는 것이다. 하지만 이유는 알아야 한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
 
int main()
{
    char str1[] = "Happy Ending";
    char str2[] = "Happy Ending";
 
    if (str1 == str2)
    {
        puts("equal");
    }
    else
    {
        puts("different");
    }
 
    return 0;
}
cs

 

8행에서는 정말 문자열을 비교하고 있을까?

배열의 이름은 배열의 시작주소다. 따라서 8행에서 비교하는 것은 배열의 시작주소다.

다시 말해  str1 에서  H 의 주소와  str2 에서  H 의 주소를 비교한다는 것이다. 

 str1 의  H 와  str2 의  H 를 비교하는 것이 아니다.

 

그래서 문자열을 비교하려면  strcmp  함수를 써야 하는 것이다.

 strcmp  함수는 각 문자열의 첫 글자부터 마지막 글자, 즉 널 문자까지 하나씩 비교한다.

구체적인 비교 방식은 다음과 같다.

 

① "ABCDE", "ABCDE"

 

첫 번째 문자부터 널 문자까지 두 문자열의 모든 내용이 같다.

따라서 A부터 널 문자까지 비교를 진행한 후 0을 반환한다.

 

 

② "ABDDE", "ABCCE"

 

첫 번째 문자부터 두 번째 문자까지는 모두 같지만, 세 번째 문자는 다르다.

따라서 세 번째 문자까지 비교를 진행한 후 비교를 중단한다. 그리고 양수를 반환한다.

 

 strcmp  함수는 두 문자가 다르면 바로 비교를 중단하고 값을 반환하므로, 그 뒤 문자의 동일 여부는 의미가 없다. 그러니까 여기서는 세 번째 문자가 다르므로, 네 번째 문자가 D와 C로 다른 것은 의미가 없다는 것이다.

 

 

③ "ABCD", "ABCDE"

 

첫 번째 문자부터 네 번째 문자, 그러니까 A부터 D까지는 같다.

그런데 다섯 번째가 문제다. "ABCD"는 네 글자고, "ABCDE"는 다섯 글자이기 때문이다.

이 경우 첫 번째 문자열의 널 문자와 두 번째 문자열의 E가 비교되므로 여기까지만 비교한 후 음수를 반환한다.

 

 

 strcmp  함수는 두 문자열이 같으면 0, 첫 번째 문자열이 더 크면 양수, 두 번째 문자열이 더 크면 음수를 반환한다. 다시 말해 같으면 0, 아니면 0이 아닌 값을 반환한다.

일반적으로 문자열의 동일 여부를 검사하는 용도로 사용되기 때문에, 언제 양수가 반환되고 언제 음수가 반환되는지는 중요한 사항이 아니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <stdio.h>
#include <string.h>
 
int main()
{
    char str1[10= "ABCDDFGH";
    char str2[10= "ABCDEFGH";
 
    if (!strncmp(str1, str2, 4))
    {
        puts("앞의 네 글자는 같습니다.");
 
        if (!strcmp(str1, str2))
        {
            puts("나머지도 같네요");
        }
        else
        {
            puts("나머지는 다르네요");
        }
    }
    else
    {
        puts("두 문자열은 다릅니다.");
    }
 
    return 0;
}
cs

 

 

 

다음과 같이 간단한 인증을 구현할 수도 있다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <stdio.h>
#include <string.h>
 
int main()
{
    char id[20];
    char pw[20];
    char user_id[20= "id";
    char user_pw[20= "password";
 
    fputs("아이디 입력", stdout);
    fgets(id, sizeof(id), stdin);
    fputs("비밀번호 입력", stdout);
    fgets(pw, sizeof(pw), stdin);
 
    if (!strcmp(id, user_id))
    {
        if (!strcmp(pw, user_pw))
        {
            puts("로그인 되었습니다.");
        }
        else
        {
            puts("패스워드를 확인하세요.");
        }
    }
    else
    {
        puts("아이디를 확인하세요.");
    }
 
    return 0;
}
cs

 

 

 

 

2. strcmp 함수의 반환값

 

앞에서는 양수, 음수 또는 0이 아닌 값이라고 뭉뚱그려 말했지만, 엄밀히 말하면 두 문자의 아스키 코드 값의 차이다.

 

물론 이것은 컴파일러에 따라 다르다. 컴파일러에 따라 1, 0, -1이 출력되기도 한다. 

Visual Studio 2017이 그 예다.

 

gcc라는 컴파일러의 경우 매개변수에 문자 배열을 전달해 비교하면 아스키 코드 값의 차이가 반환되고, 큰 따옴표를 써서 문자열 자체를 전달해 비교하면 1, 0, -1이 반환된다.

 

 

 

'Programming > C' 카테고리의 다른 글

문자열을 숫자로 변환하는 함수  (0) 2019.05.18
sprinf, sscanf 함수  (0) 2019.05.18
문자열 길이 측정, 복사, 연결 함수  (0) 2019.05.13
문자열 입출력 함수  (0) 2019.05.07
문자 입출력 함수  (0) 2019.05.05