<개인공부>/[C언어, C++]

[C언어/C++] strcmp, strncmp 함수(문자열 비교)에 대해서

사용자 BlockDMask 2020. 1. 2. 00:00
반응형

안녕하세요 BlockDMask입니다.

오늘은 c/c++에서 두개의 문자열이 같은지, 다른지 다르면 어떤식으로 다른지 검사할 수 있는 strcmp 함수. 

문자열 비교 함수인 strcmp 함수를 알아 보려고 합니다.


오늘은 strcmp, strncmp 두가지 함수를 알아볼것 인데요. 두 함수는 크게 차이가 없습니다. 

단지 strcmp -> str n cmp 이어서 n 이 추가된것인데요 이 n이 뜻하는 것은 검사할 문자의 개수를 지정하는 것 입니다.

자 그럼 이제 시작해보려 합니다. 예제를 신경써서 만들었으니 끝까지 봐주시면 좋겠습니다. 미리 감사합니다.


▶ C언어, C++ 문자열 관련 함수들 포스팅

문자열 입출력 함수 puts, gets [바로가기]

문자열 검색 strchr [바로가기]

문자열 탐색 함수 strstr [바로가기]

문자 입출력 함수  getchar, putchar [바로가기]

문자열 복사 strcpy, strncpy [바로가기]

문자열 이어붙이기 strcat [바로가기]

문자열 길이 구하기 strlen [바로가기]


<목차>

1. strcmp, strncmp 함수의 정의와 설명

2. 문자열 비교 (strcmp, strncmp) 함수 예제


1. strcmp, strncmp 함수의 정의와 설명


 헤더파일

C언어 : <string.h>

C++ : <cstring>


 정의

int strcmp(const char* str1, const char* str2)

int strncmp(const char* str1, const char* str2, size_t n);


 strcmp 함수 매개변수 설명

첫번째 매개변수 str1 : 비교할 문자열1

두번재 매개변수 str2 : 비교할 문자열2


strncmp 함수 매개변수 설명

첫번째 매개변수 str1 : 비교할 문자열1

두번재 매개변수 str2 : 비교할 문자열2

세번째 매개변수 n : 비교할 문자열 길이  


이 n 의 범위가 중요합니다.  

타입이 size_t 입니다. size_t는 unsigned int 로 되어있습니다. 그러므로 0보다는 큰 값이 들어와야 합니다. 또한 str1, str2 문자열보다 큰 값을 넣게 되면 알아서 문자열의 전체를 비교합니다. 

예를들어 str1이 문자 5개, str2가 문자 10개로 이루어져있을 경우 n 에 10넣든 100넣든 str1이 5이므로 5개 까지의 문자만 비교하게 됩니다. 


그럼 strncmp 함수 세번째 인자 n에 -1(음수) 혹은  0을 넣게 되면 어떻게 될까요? 이것은 이따가 예제에서 풀어보겟습니다


strcmp, strncmp 설명

- 매개변수로 들어온 두개의 문자열을 비교 하여 문자열이 완전히 같다면 0을 반환하고, 다르면 음수 혹은 양수를 반환하는 함수입니다.

- 여기서 -1, 1은 매개변수로 들어온 문자열들을 비교하다가 다른 문자가 나왔을때 그 문자의 아스키 코드 값에 의해서 정해집니다. 

(1) str1 < str2 인 경우에는 음수 반환

(2) str1 > str2 인 경우에는 양수 반환

(3) str1 == str2 인 경우에는 0을 반환 합니다.


- strcmp, strncmp 함수가 앞에서 부터 각각 문자를 비교할때, 아스키 코드값으로 비교를 하게 됩니다.

- 각 문자를 아스키 코드로 비교 하기 때문에 아래와 같은것이 가능합니다.

(1) 대소문자 구분

(2) 각 문자별 숫자가 정해져있으므로 대소 비교 가능


 간단예시(strcmp) 

char str1[] = “BlockDMask”; 

char str2[] = “BlockDMask”; 

strcmp(str1, str2);             // 문자열이 같으므로 0 

strcmp(str1, BlockFMask”); // D < F 이므로 음수 반환

strcmp(str1, BlockAMask”); // D > A 이므로 양수 반환


 간단예시(strncmp)

const char* str1 = “BlockDmask

const char* str2 = “BlockFmask

strncmp(str1, str2, 5); //‘Block” 까지만 검사하므로 0 반환

strncmp(str1, str2, 6);  // D < F 이므로 음수 반환



2. 문자열 비교 (strcmp, strncmp) 함수 예제


 strcmp 함수 예제

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
#include<string.h>    //strcmp
#include<stdio.h>    //printf
 
int main(void)
{
    const char* str1 = "BlockDMask";
    const char* str2 = "Block";
    const char* str3 = "BlockDMask";
    const char* str4 = "BlockFMask";
    const char* str5 = "BlockAMask";
 
    //문자열 비교 반환값 확인
    printf("strcmp(%s, %s)\t = %d\n", str1, str2, strcmp(str1, str2));
    printf("strcmp(%s, %s)\t = %d\n", str1, str3, strcmp(str1, str3));
    printf("strcmp(%s, %s)\t = %d\n", str1, str4, strcmp(str1, str4));
    printf("strcmp(%s, %s)\t = %d\n", str1, str5, strcmp(str1, str5));
 
    //문자열이 같은지를 판단할때는 이와같이 사용합니다.
    if (strcmp(str1, str2) == 0)
    {
        printf("%s, %s 는 같습니다.", str1, str2);
    }
    else
    {
        printf("%s, %s 는 다릅니다.", str1, str2);
    }
 
    return 0;
}
cs


예제 결과


문자의 길이가 다른 경우에 문자열이 긴쪽이 문자열이 크다 그래서 1을 반환한다 이렇게 생각하는것도 맞습니다. 좀더 정확하게 보면


C언어 스타일의 문자열 char*, char[] 의 끝에는 문자열의 끝을 알리는 ‘\0’ 들어가 있습니다. 

이것은 null을 의미하는데요 이걸 아스키 코드 표로 보게 되면 0번을 나타냅니다. 그렇기 때문

“BlockDMask\0”; 

“Block\0”;

이렇게 두개의 문자열을 앞에서 부터 비교를 쭉쭉쭉 하다가

‘D’와 ‘\0’ 를 비교하게 됩니다. 아스키 코드 표를 보면 \0 (NULL)은 0번을 나타내기 때문에, '\0' 은 그 어떤 문자보다 작습니다.

'D' > '\0'이므로 strcmp(“BlockDMask”, “Block”)에서 첫번째 매개변수로 들어온 문자열이 더 크므로 값이 1(더 정확하게는 양수)이 나오게 됩니다.


"문자열이 같다 아니다"를 비교할때는 0이냐 아니냐를 비교하면 되므로 음수인지 양수인지는 많이 사용하지는 않긴 합니다.

하지만 정확히 알아두면 좋을 듯 합니다.


 strncmp 함수 예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include<string.h>    //strncmp
#include<stdio.h>    //printf
 
int main(void)
{
    char str1[] = "BlockDMask";
    char str2[] = "Block";
    char str3[] = "BlockAAAAA";
    
    printf("strncmp(%s, %s, -1)\t = %d\n", str1, str2, strncmp(str1, str2, -1));
    printf("strncmp(%s, %s, 0)\t = %d\n", str1, str2, strncmp(str1, str2, 0));
    printf("strncmp(%s, %s, 5)\t = %d\n", str1, str2, strncmp(str1, str2, 5));
    printf("strncmp(%s, %s, 6)\t = %d\n", str1, str2, strncmp(str1, str2, 6));
    printf("strncmp(%s, %s, 1000) = %d\n", str1, str2, strncmp(str1, str2, 1000));
 
    printf("strncmp(%s, %s, 5)\t = %d\n", str1, str3, strncmp(str1, str3, 5));
    printf("strncmp(%s, %s, 555)\t = %d\n", str1, str3, strncmp(str1, str3, 555));
 
    return 0;
}
cs


예제 결과


strncmp 함수의 세번재 매개변수 n에 0을 넣은 경우에는 항상 0이 나오게 됩니다.

strncmp 함수의 세번째 매개변수에 -1을 넣은 경우unsigned int 타입에서 언더플로우가 일어나기 때문에 최대값이 들어가므로 매개변수로 들어온 문자열을 끝까지 비교를 하게 됩니다.

1000을 넣건 10000을 넣건 함수 내부에서 매개변수로 들어온 str1, str2 문자열의 최대길이까지 끝까지 비교합니다.

*여기서 끝까지 비교한다는 것은 다른것이 나올때까지 비교하거나 끝을 감지했을때 까지 입니다.


 그럼 이건 어떤식으로 나오게 될까요 ?

strcmp(‘BlockD\0Mask”, ‘BlockD\0AAAA”);


정답과 이유를 댓글로 달아주세요. 

(맞추신 분에 대한 상품은 ... 없습니다.. ..)


이상으로 문자열 비교함수인 strcmp와 strncmp 에 대해서 알아보았습니다. 감사합니다.


반응형