본문 바로가기
IT/PROGRAM

리눅스 C언어 문자열 분리 strtok 사용법 그리고 대체함수

by SidePower 2020. 10. 16.

문자열 컨트롤하는 것은 Java C Python C# 등
프로그램 언어 구분없이 반드시 알고 있어야 됩니다.


특히 문자열 자르기는 java나 C#은 split이란
함수를 통해 한줄 코딩으로 잘린 문자열을 얻을 수 있게 심플하게 구현할 수 있는데요.

C언어는 strtok 함수가 있기는 하지만
한두줄로 끝나는 게 아닙니다.
사용법을 숙지해야만 원하는 문자열을 얻을 수 있기 때문에
C언어를 하셨던 분이라도 하나하나 의미를
알고 있는게 활용하시기 편하실 거예요.

strtok 함수 원형
char * strtok ( char * str, const char * delimiters ):

문자열을 구분자에 의해 나눠진 문자열 조각을 토큰이라고 부릅니다.
긴 문자열을 특정 문자 또는 특정 문자열을 구분자(delimiters)로 정하고

구분자를 기준으로 잘린 문자열 토근을 얻는 함수입니다.
리턴 값은 토근 문자열의 시작 주소이고
만약에 더 이상 구분자가 없으면 NULL값을 리턴합니다.

그래서 함수 이름을 strtok로 지은 거 같네요.

string.h 해더 파일에 선언되어 있습니다.

 


간단한 샘플 소스를 만들었습니다.

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

int main()
{
    char str[] = "hello man#I am#very busy.#nice meet you!";
    char * pstr;
    pstr = strtok(str,"#");            -------------- 1
    while (pstr != NULL)              -------------- 2
    {
        printf("Token [%s]₩n");          ------- 3
        pstr = strtok(NULL, "#");            ------- 4
    }
    return 0;
}

결과

Token [hello man]
Token [I am]
Token [very busy.]
Token [nice meet you!]

핵심 부분은 숫자를 넣었습니다. 1 2 3 4

1번 구문
pstr = strtok(str,"#");
str 문자열에서 첫 문자부터 비교하면서 구분자 # 이 있을 때까지 찾습니다.
구분자를 찾게 되면 str 문자열에서 찾기 시작한 첫 번째 주소를 리턴합니다.
그리고 구분자가 있던 자리에 NULL 값을 넣습니다.
그래서 첫번째 토큰 문자열 값을 얻게 됩니다.

2번 구문
while (pstr != NULL)
두 번째 토큰부터는 반복문을 통해 토근 문자열이
있을 때까지 찾아야 됩니다.

3번 구문
printf("Token [%s]₩n");
토큰 문자열을 사용하는 부분인데요.
저는 단순하게 확인을 위해 출력했습니다.

4번 구문
pstr = strtok(NULL, "#");
첫 번째 인자 값에 str 문자열 주소 값 대신 NULL값을 넣으면
strtok 함수 내부적으로 이전에 찾은 토큰 문자열의
크기만큼을 이동하고 그 위치에서 다시 구분자를 이용해서
토큰 문자열을 찾게 됩니다.
생각해보면 NULL이면 바로 직전에 기억된 주소에서 찾기를 시작하는 거 같네요.ㅋ
만약에 NULL값을 넣지 않고 str 문자열 시작 주소를 그대로 넣으시면
첫 번째 토큰 문자열만 계속 찾게 됩니다.

일할 때 문자열 잘라서 사용해야 되는 경우는
대체로 필드가 일정하게 정해져 있습니다.
구분자는 일마다 다르지만 대게 콤마(,)로 해서
이름, 연락처, 주소, 담당업무, 월급.. 이렇게요.

한 줄로 끝나게 strtok를 이용해서 직접 공통 함수를 만들어 봤습니다.
허접하지만 저는 잘 쓰고 있습니다.
참고로만 봐주세요.

strtok를 이용한 공통 함수 만들기

void v2_strtok(char * des,char * src,char * delmit)
{
    char * pp;
    if ( src != NULL )
        pp = strtok(src,delmit);
    else
        pp = strtok(NULL,delmit);
    memcpy(des,pp,strlen(pp));
}


v2_strtok 활용

struct _insa {
    char name [ 20 ];
    char phone [ 15 ];
    char addr [ 80 ];
};
typedef struct _insa insa;

int main()
{
    insa INSA;
    memset(&INSA,0x00,sizeof(INSA));
    char str[] = "kim man,010-1234-9999,gyeognam";

    v2_strtok(INSA.name,str,",");
    v2_strtok(INSA.phone,NULL,",");
    v2_strtok(INSA.addr,NULL,",");

    printf("INSA.name [%s]₩n",INSA.name);
    printf("INSA.phone [%s]₩n",INSA.phone);
    printf("INSA.addr [%s]₩n",INSA.addr);

    return 0;
}


결과

INSA.name [kim man]
INSA.phone [010-1234-9999]
INSA.addr [gyeognam]

감사합니다.

반응형

댓글