C/C++ 관련 포스팅 목록
2020/06/28 - [Linux/C] - C/C++ API strchr(특정 문자 위치 검색)
2020/06/27 - [Linux/C] - C/C++ API access(파일 존재 여부 확인)
2020/06/26 - [Linux/C] - C/C++ API sprintf(문자열 붙이기)
목차
API의 필요성
이전 strchr API 관련 포스팅에서 문자열에서 특정 문자가 있는 위치를 파악하는 방법에 대하여 알아보았습니다. 여기서 조금 더 나아가면 전체 문자열에서 특정 문자를 기준으로 나눈 문자열들을 알아야 할 때가 있습니다. 예를들어 "Hello world korea yoo" 라는 문자열이 있다면 공백(Space) 문자로 나눌 경우 "Hello", "world", "korea", "yoo" 라는 문장 4개로 나뉘어집니다.
이와 같이 개발자가 특정 프로그램을 개발하면서 엄청 긴 글이 있을 때 특정 단어로 나눌 필요가 있다면 C언어의 strtok API를 사용하면 됩니다. strtok은 내부 함수 구현부에서 첫번째, 두번째 등 특정 단어를 지속적으로 찾아가며 해당 위치의 문장을 출력합니다.
strtok은 원본 문자열을 특정 단어 단위로 자르면서 자른 부위를 0의 값을 저장하여 하나의 문자열을 구성합니다.
따라서 원본의 문자열이 수정되도 상관 없는 경우 strtok을 사용합니다.
또한 strtok으로 원본 문자열에서 특정 문자를 이용하여 자른 이후는 반드시 NULL 포인터를 전달하여 다음 문장을 나누어야합니다. 이 부분은 예제를 통해 이해하는 것이 빠릅니다.
함수 구조 설명
#include <string.h>
char *strtok(char *str, const char *delim);
#인자
char *str
- 문자열을 자르고 싶은 원본 문자열의 포인터(첫 번째 자른 이후는 반드시 NULL을 입력해야함)
const char *delim
- 자를 단위 문자
#반환
char *
- 특정 문자 단위로 자른 뒤 첫번째 문자열 포인터
strtok은 한번 호출한다고해서 특정 문자로 자른 후의 모든 단어의 포인터가 반환되지는 않습니다. strtok을 호출하여 반환되는 값이 NULL 이 될 때까지 반복문을 호출해야합니다.
예제 목표
이번 포스팅에서는 strtok을 활용하여 문자열을 나누는 방법과 원본의 문자열이 수정될 수 있는 문제점을 이해하는 것이 목표입니다. 개발 환경은 Linux Ubuntu 16.04 LTS x64 환경에서 진행하도록 하겠습니다.
코드 작성
$ cd /tmp
$ mkdir strtok_example; cd strtok_example
$ vim strtok_test.c
#include <stdio.h>
#include <string.h>
void main() {
char text[] = "hello world korea yoo";
char *splited_str_p = strtok(text, " ");
while (splited_str_p != NULL) {
printf("잘린 문자열 : %s\n", splited_str_p);
splited_str_p = strtok(NULL, " ");
}
printf("\n\n원본 text 변수의 문자열 : %s\n", text);
}
위와 같이 text 변수에는 "hello world korea yoo" 라는 문자열을 가리키고 있으며 공백문자(" ")로 나누어 출력하고 있습니다. 나눈후 첫번째 잘린 문자 포인터는 splited_str_p에 저장되고 strtok은 자른 공백문자(" ") 위치에 0(NULL) 값을 저장합니다. 따라서 반환된 splited_str_p 에는 정상적인 문자열 포인터가 저장됩니다.
이후 다시 자르기 위해선 strtok에 text 포인터를 다시 전달하는게 아니라 반드시 NULL을 전달해야 합니다. strtok 함수 내부에서 기존 잘랐던 위치를 기억하고 있기 때문에 이렇게 설정해야합니다.
실행
$ cd /tmp/strtok_example
$ gcc -c strtok_test.c -o strtok_test.out
$ gcc -o strtok_test strtok_test.out
$ ./strtok_test
결과
위와 같이 공백 문자로 잘른 단어들이 차례대로 출력되고 있습니다. 마지막으로 출력된 원본 text의 변수는 원래의 값이 수정되어 비정상 내용을 출력하고 있습니다. 따라서 strtok API를 사용할 때는 원본 문자열이 변경되더라도 상관없는 경우에 사용해야 합니다.