안녕하세요. BlockDMask 입니다.
오늘 공부할 함수는 문자열을 일정 기준을 정해서 싹둑싹둑 자를 수 있는 strtok 함수입니다.
C언어 strtok 함수에 대해서 한번 알아보러 가보겠습니다.
<목차>
1. strtok 정의와 함수 설명
2. strtok 예제1
3. strtok 예제2
1. C/C++ strtok 정의와 함수 설명
▶ strtok 헤더파일
C언어 : <string.h>
C++ : <cstring>
▶ strtok 함수 정의
char* strtok(char* str, char* delimiters);
strtok 이라는 함수의 이름을 분석해보면 str + tok 인데요.
string을 tokenize한다. 라고 표현할 수 있습니다. 문자열(string)을 토큰(token)처럼 조각조각 내는 함수 입니다.
char* 타입의 문자열 str을 첫번째 매개변수로 받아서, 두번째 매개변수로 들어온 char* 타입의 구분자를 기준으로
문자열을 이쁘게 잘라서 문자열의 포인터를 하나씩 하나씩 반환하는 함수 입니다.
반환값은 포인터를 반환하는데 자른 문자열을 가리키는 char* 입니다. 포인터를 통해서 어떤식으로 문자를 구분하는지 아래 strtok 함수 동작 원리를 보면 이해가 쉬울것 같습니다.
strtok 함수를 통해서 우리는 이런걸 할 수 있습니다.
"코로나19 의료진 여러분 힘내세요." 이렇게 띄어쓰기가 되어있는 문장에서 띄어쓰기 제외하고 단어들을 가지고싶다 할때
strtok을 이용하면
"코로나19" "의료진" "여러분" "힘내세요."같이 띄어쓰기를 제외한 단어들만 가지고 올 수 있습니다.
이럴때도 유용하겠죠. 환자들의 이름들이 "김환자, 박대구, 이시국, 김마스크" 이런식으로 되어있다고 할 때
이름만 가지고 오고싶다. 할때 strtok("문자열", "구분자")를 이용해서
쉼표(,)와 띄어쓰기( )를 구분자로 넣어서 환자의 이름만 쏙쏙 가지고 올 수 있습니다.
▶ strtok 함수 동작 원리를 세가지로 설명해보려 합니다.
예를들어 "Block D Mask"라는 문자열이 있고 " " 공백(띄어쓰기)을 기준으로 문자열을 자른다고 할때, 이런식으로 흐름이 진행됩니다.
첫번째 인자에는 짜를 문자열, 두번째 인자는 구분할 기준을 집어 넣습니다.
char* ptr = strtok("Block D Mask", " ");
그러면 strtok 이라는 함수는 문장에서 구분자로 들어온 " " 공백을 찾습니다.
알맞은 구분자를 " " 를 찾게 되면 해당 구분자를 문장의 끝을 알리는 \0 으로 바꾸어 줍니다.
strtok의 첫번째 반환값은 "Block"이 됩니다.
이 상태에서 또다시 strtok(NULL, " "); 함수를 호출하게 되면 이전에 찾은 구분자 뒤에서 부터 다시 구분자를 찾게 됩니다.
"D Mask"라는 문자가 이제 남았는데요. D 다음에있는 띄어쓰기를 보고 strtok 함수는 그 띄어쓰기를 '\0'로 바꾸어 줍니다.
"D\0Mask" 라는 문장이 되면서, strtok 함수는 문자열 "D"를 가리키는 포인터를 반환하게 됩니다.
이 상태에서 또다시 strtok(NULL, " "); 함수를 호출하게 되면 아까 기억했던 "D\0Mask" 함수에서 변환했던 \0이부분의 바로 뒤에서 부터 구분자를 찾게되는데, 이때!!!!!!! Mask" 하고 문자가 끝나기 때문에 M에서부터 문자열끝까지를 가리키는 "Mask"를 가리키는 포인터를 반환하게 됩니다.
이 상태에서 또다시 strtok(NULL, " "); 함수를 호출하면 문자열의 끝까지 탐색했기 때문에 strtok 함수는 NULL을 반환하게 됩니다.
눈치 채셨는지 모르지만, strtok 함수를 처음 불러줄때만 원하는 문자열을 집어넣고 그 다음부터는 첫번째 인자에 NULL을 넣어주는 것을 알 수 있는데요, 이는 strtok 함수에게 "이전에 너가 구분자를 찾았던 그 문자열 주소에서 부터 다시 찾아달라"는 뜻을 가지고 있다고 생각하면됩니다.
또 눈치 채셨는지 모르지만, strtok 함수는 한번에 이쁘게 딱 문자열을 분리해주는 함수가 아닙니다.
strtok 함수가 NULL을 반환할 때 까지 계속해서 불러줘야하는 함수입니다.
2. 코드로 보는 strtok 함수 흐름
위에서 말한 strtok 함수의 흐름을 코드에서 살펴보면 이렇습니다.
1 2 3 4 5 6 7 | char str[] = "Block D Mask."; //구분할 문자열 char *ptr = strtok(str, " "); //첫번째 strtok 사용. while (ptr != NULL) //ptr이 NULL일때까지 (= strtok 함수가 NULL을 반환할때까지) { printf("%s\n", ptr); //자른 문자 출력 ptr = strtok(NULL, " "); //자른 문자 다음부터 구분자 또 찾기 } | cs |
3. 그림으로 보는 strtok 함수 흐름
글로 설명하니 저도 이해가 잘 안가네요. 미천한 PPT 실력을 뽐내보도록 하겠습니다.
그림으로 보니 이해가 좀 쉬워졌을까요?
두번째 인자로 들어온 구분자를 찾아서 '\0'로 바꿔준다. 이것만 기억하면 될듯 합니다.
그럼이제 예제들을 보러 가시죠.
2. C언어, C++ strtok 예제1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #include<stdio.h> #include<string.h> //C++ : <cstring> int main(void) { char str[] = "Kim,Park,Lee,Choi,Seo"; char *ptr = strtok(str, ","); //구분자는 콤마(,)입니다. while (ptr != NULL) { printf("%s\n", ptr); //자른 문자 출력 ptr = strtok(NULL, ","); } return 0; } | cs |
▷예제 결과
문자열이 콤마(,)를 기준으로 잘 잘리는걸 볼 수 있습니다.
3. C++, C언어 strtok 예제2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #include<stdio.h> #include<string.h> int main(void) { char str[] = "x + y - z + 9 = 1000"; char *ptr = strtok(str, "+-= "); //구분자는 "+-= "입니다. while (ptr != NULL) { printf("%s\n", ptr); ptr = strtok(NULL, "+-= "); } return 0; } | cs |
'<개인공부> > [C언어, C++]' 카테고리의 다른 글
[C언어/C++] 시간 관련함수에 대해서 (time, localtime, ctime, asctime) (6) | 2020.08.24 |
---|---|
[C언어/C++] fgets, fputs 함수에 대해서 (2) | 2020.06.22 |
[C언어/C++] fputc, fgetc 함수에 대해서 (0) | 2020.06.16 |
[C언어/C++] 파일 입출력 fopen, fclose 함수에 대해서 (1) | 2020.06.12 |
[C언어/C++] strcmp, strncmp 함수(문자열 비교)에 대해서 (13) | 2020.01.02 |
[C언어/C++] strchr 함수(문자 검색)에 대해서 (3) | 2019.12.31 |
[C언어/C++] strlen 함수(문자열 길이)에 대해서 (1) | 2019.12.06 |
[C언어/C++] isdigit (숫자를 판단하는 함수) (2) | 2019.11.12 |