본문 바로가기
c언어

c언어 문자열 처리 라이브러리에 대하여 알아보기 2(문자열 비교하기, 문자 및 문자열 검색하기, 문자열 토큰 분리하기)

by 개발자 L 2022. 12. 30.
반응형

c언어 문자열 처리 라이브러리에 대하여 알아보기 2(문자열 비교하기, 문자 및 문자열 검색하기, 문자열 토큰 분리하기)

네 안녕하세요, 이번 포스팅에서는 저번에 다뤘었던 문자열 처리 라이브러리를 이어서 다루겠습니다.

문자열 처리 라이브러리 함수는 설명드릴 것이 많아서 파트를 나눴습니다.

이번 시간에는 문자열을 비교하는 방법, 문자 및 문자열을 검색하는 방법,

문자열 토큰을 분리하는 방법에 대하여 알아보도록 하겠습니다.

그럼 지금부터 함께 보시죠.

 

1. 문자열 비교하기

문자열을 비교할 때는 strcmp()라는 함수를 써서 나타냅니다.

이런 식으로 말이죠.

int result = strcmp("dog", "dog");

 이런 식으로 씁니다.

주로 문자열을 비교한다고 한다면 문자열이 같은 지 다른 지를 비교합니다.

그리고 여기서 주의를 할 점은, 문자열이 같을 시에 반환되는 값이 0이라는 점입니다.

보통은 참일 경우는 1이 반환이 되지만, 이 함수는 그 반대이기 때문에 잘 알아두셔야 합니다.

그리고 strcmp() 함수가 문자열을 비교하는 원리는 아스키코드 값을 비교하여 계산합니다.

그 이유는 문자열은 사전에 존재하지 않는 기호들도 대거 등장하기 때문에,

그만큼 정밀해야 정확한 값을 추릴 수 있기 때문입니다.

그래서 이 코드값을 비교해서 다음 표에 기재된 값을 반환합니다.

반환값 s1, s2의 관계
<0 s1이 s2 보다 앞에 있다.(s1이 코드값이 더 앞에 있으므로, 더 작다)
0 s1과 s2가 같다.(두 문자열의 코드값이 같다.)
>0  s1이 s2 보다 뒤에 있다.(s1의 코드값이 뒤에 있으므로, 더 크다.)

이러한 관계를 가집니다.

그럼 이를 이용하여 사용자가 입력하는 서로 다른 두 가지의 단어들을 입력해서

비교하는 프로그램을 작성해보도록 하겠습니다.

#include <stdio.h>
#include <string.h>

int main()

{
    char s1[80];
    char s2[80];
    int result;

    printf("첫 번째 단어를 입력하세요 : ");
    scanf("%s", s1);

    printf("두 번째 단어를 입력하세요 : ");
    scanf("%s", s2);

    result = strcmp(s1, s2);

    if(result < 0)
    {
        printf("%s가 %s 보다 더 앞에 있습니다.\n", s1, s2);
    }

    else if(result == 0)
    {
        printf("%s와 %s가 같습니다.\n", s1, s2);
    }

    else
    {
        printf("%s가 %s 보다 더 뒤에 있습니다.\n");
    }

    return 0;
}

이렇게 한 번 작성을 해봤습니다.

그럼 결과를 한 번 보도록 하겠습니다.

첫 번째 단어를 입력하세요 : cat
두 번째 단어를 입력하세요 : dog
cat가 dog 보다 더 앞에 있습니다.

이렇게 문제 없이 나오는 것을 볼 수가 있습니다.

 

2. 문자 및 문자열 검색하기

이번에는 문자와 문자열을 검색하는 방법에 대하여 알아보도록 하겠습니다.

문자와 문자열을 검색하는 메커니즘은 똑같습니다.

다만 사용하는 함수명이 살짝 다릅니다.

그럼 문자를 검색하는 방법부터 보도록 하겠습니다.

 

2 - 1. 문자 검색하기

문자 검색을 할 때는 strchr() 함수를 써서 나타냅니다.

이런 식으로 말이죠.

char *p = strchr("dog", "g");

보통 문자를 검색한다고 하면, 본인이 어떤 문자열에서 찾고자 하는 문자가 있을 때 검색하는 것을 말합니다.

그래서 제일 첫 문자 부터 차례로 검색을 해서 문자를 찾으면 해당 문자의 주소를 반환하므로,

포인터를 쓰게 됩니다.

그리고 본인이 찾고자 하는 문자가 존재하지 않는다면, NULL 값을 반환합니다.

그럼 특정 단어를 찾아서 그 위치를 출력하는 프로그램을 한 번 작성을 해보도록 하겠습니다.

#include <stdio.h>
#include <string.h>

int main()

{
    char s[] = "language";
    char c = 'g';
    char *p;
    int location;

    p = strchr(s, c);
    location = (int)(p - s);

    if(p != NULL)
    {
        printf("%s 에서 첫 번째 %c 가 %d 에서 발견되었습니다.\n", s, c, location);
    }

    else
    {
        printf("%c 가 발견되지 않았습니다.\n", c);
    }

    return 0;
}

여기서 위치는 정수형으로 표현이 된다는 점에 유의하셔야 합니다.

우리가 문자의 위치를 구하는 원리는 중, 고등학교 수학 시간에 선분의 길이를 구하는 원리와 같습니다.

그래서 큰 거에서 작은 것을 빼는 원리로 그 위치를 구합니다.

그래서 이를 반환을 할 때 캐스팅(형 변환)을 해서 출력을 해주어야 합니다.

그래서 문자의 주소가 담겨져 있는 변수 p에서 전체 문자 배열의 시작 주소 s를 빼서 출력하여 나오는 것이 정수형이기에

캐스팅을 하지 않으면 에러가 납니다.

그럼 결과를 보도록 하겠습니다.

language 에서 첫 번째 g 가 3 에서 발견되었습니다.

결과가 잘 나온 것을 확인할 수 있습니다.

여기에서 조금 의아한 부분이 있을 수 있는데,

육안으로 보기에는 위치가 4번째인데 3이 출력이 되었죠?

항상 디지털 체계에서는 인덱스 주소의 시작값은 0이기 때문에 인덱스 주소가 잘 출력이 되었음을 알 수 있습니다.

반응형

 

2 - 2. 문자열 검색하기

이번에는 문자열을 검색하는 방법에 대하여 알아보도록 하겠습니다.

문자열을 검색할 때 쓰는 함수는 strstr()입니다.

사용 방법은 아래와 같습니다.

char *p = strstr("dog", "do");

쓰는 방법은 문자 검색하는 방법과 똑같은데, 다만, 한 개의 문자를 검색하느냐,

두 개 이상의 문자열을 검색하느냐의 차이가 있습니다.

그럼 strstr() 함수를 이용하여 간단한 코드를 한 번 짜보도록 하겠습니다.

#include <stdio.h>
#include <string.h>

int main()

{
    char s[] = "A joy that's shared is a joy made double"; // string
    char sub[] = "joy"; // substring
    char *p;
    int location;

    p = strstr(s, sub);
    location = (int)(p - s);

    if(p != NULL)
    {
        printf("%s 에서 첫 번째 %s 가 %d 에서 발견되었습니다.\n", s, sub, location);
    }

    else
    {
        printf("%c 가 발견되지 않았습니다.\n", sub);
    }

    return 0;
}

이렇게 한 번 작성을 해봤습니다.

그럼 결과를 한 번 보도록 하겠습니다.

A joy that's shared is a joy made double 에서 첫 번째 joy 가 2 에서 발견되었습니다.

결과가 잘 나왔음을 볼 수 있습니다.

그리고 여기서 joy는 문자열이기 때문에,

joy가 시작되는 위치를 출력을 하게 됩니다.

그래서 joy의 j가 시작되는 인덱스 주소가 2이기 때문에 이렇게 나온 것입니다.

 

3. 문자열 토큰 분리하기

이번에는 문자열 토큰 분리를 해보도록 하겠습니다.

문자열 토큰을 분리를 한다는 것은,

문장에서 단어를 분리하는 것입니다.

다시 말하면 토큰이란 문법적으로 더 이상 나눌 수 없는 제일 기본적인 언어 요소를 뜻합니다.

한글로 따지면 형태소와 같은 기능을 하는 것이죠.

형태소도 더 이상 나눌 수 없는 한글 언어의 최소 단위니까요.

그리고 한 가지 예시로, 문자열은 공백 역시 문자의 일부로 취급을 하기 때문에 토큰으로 취급을 할 수 있습니다.

사용 함수는 strtok()이란 함수인데, 이를 이용해서 토큰을 분리하는 분리자를 사용자가 마음대로 지정이 가능합니다.

사용 방법은 이러합니다.

char s[] = "Hello world";
char delimit[] = " ";
char *p = strtok(s, delimit);

이러한 형식으로 사용을 합니다.

의미는 delimit 변수 속에 들어있는 문자가 공백이기 때문에,

공백으로 문자를 분리하겠다는 뜻이 됩니다.

그리고 이러한 분리자를 통하여 토큰을 읽어내는 방법은 아래와 같습니다.

t1 = strtok(s, " ");
t2 = strtok(NULL, " ");
t3 = strtok(NULL, " ");
t4 = strtok(NULL, " ");

이렇게 제일 첫 토큰은 문자 배열의 시작 주소인 s를 쓰고, 그 뒤에 공백을 표시하지만,

그다음부터 n번째 토큰은 s가 아닌 NULL을 써야 합니다.

그 이유는 제일 첫 번째 토큰이 아니라서  위치를 모르기 때문입니다.

그래서 쓰레기 값이 들어가게 하지 않기 위해서 NULL 값을 사전에 배치를 하는 것입니다.

그럼 이를 이용하여 코드를 한 번 작성을 해보도록 하겠습니다.

#include <stdio.h>
#include <string.h>

char s[] = "Man is immortal, because he has a soul";
char separators[] = " ,\t\n";
char *token;


int main()

{
    token = strtok(s, separators);

    while(token != NULL)
    {
        printf("토큰 : %s\n", token);

        token = strtok(NULL, separators);
    }

    return 0;
}

위 코드에서는 분리자를 공백으로 하고, tab 문자와 개행 문자로 각각의 토큰을 표현하는 것으로 설정을 했습니다.

그리고 변수는 분리자를 계속 쓰기 위해서 전역 변수로 설정을 했는데,

지역 변수로 설정해도 무방합니다.

그럼 결과를 한 번 보도록 하겠습니다.

토큰 : Man
토큰 : is
토큰 : immortal
토큰 : because
토큰 : he
토큰 : has
토큰 : a
토큰 : soul

이렇게 분리를 해봤습니다.

그리고 분리자는 보기 편하도록 공백으로 지정을 했을 뿐, ":", "%" 등과 같은 문자를 분리자로 쓸 수도 있습니다.

 

여기까지 문자열 처리 라이브러리에 대하여 알아보았는데요,

다음 포스팅에서는 문자열 수치를 변환하는 방법에 대하여 알아보도록 하겠습니다.

긴 글 읽어주신 독자분들께 진심으로 감사드립니다~

반응형

댓글