티스토리 뷰

반응형


안녕하세요! C언어에서도 다양한 함수 라이브러리를 사용할 수 있는데요. 오늘 시간에는 'string.h'에 선언되어 있는 문자열의 함수 중에서 문자열을 분리하는 함수인 'strtok'에 대해서 한번 알아보도록 공부해보는 시간을 갖도록 하겠습니다.


'strtok' 함수의 역할은 문자열에서 공백과도 같이 언어적으로 의미가 없는 것을 기준으로 삼아서 문장을 단어들로 분리해준다고 볼 수 있습니다. 예를 들어서 "I have an apple"이라는 문장이 있다고 치고 공백을 기준으로 문장을 단어로 나누어 보면 'I'와 'have', 'an', 'apple'로 4개의 단어로 나누어 진 것을 확인할 수 있는데 'strtok' 함수의 결과도 바로 이런 결과를 만들어준다는 것입니다.  


char *strtok( char *s, const char *delimiter);


위에 정의된 함수의 형식은 'strtok' 함수를 나타낸 것으로 이 함수가 받는 매개변수로 char형의 포인터 변수와 'const'가 붙어서 매개변수로부터 원본을 변경할 수 없도록 정의된 포인터 변수가 있는 것을 볼 수 있습니다. 그리고 s는 분리하고자 하는 기준 문자열이고 delimiter는 분리하는 기준을 삼은 것으로 분리자라고 부르고 아까의 문장인 "I have an apple"을 s에 입력하고 공백을 delimiter에 입력하는 것인 겁니다. 물론 분리자로 공백만 있는 것이 아니라 쉼표와 탭, 줄바꾸기도 분리자로 사용될 수 있습니다.


이제는 기준 문자열이 'strtok' 함수에 의해서 어떻게 사용되는지 자세히 알아보도록 하겠습니다. 아래의 그림은 아까의 문장인 기준 문자열이 들어있는 문자 배열을 표현해본 것으로 분리자로는 공백 문자를 사용하도록 하겠습니다.(C언어에서 이를 표현하면 char s[] = "I have an apple"; char *token; token = strtok(s, " ");)

  

I

 

h

a

v

e

 

a

n

 

a

p

p

l

e

0


첫 번째로 'strtok' 함수를 실행하면 아래와 같은 결과가 나옵니다.


I

0

h

a

v

e

 

a

n

 

a

p

p

l

e

0


'I' 단어 뒤에 비어있었던 공간이 '\0'으로 값이 변한 것을 확인할 수 있는데 'strtok' 함수는 입력받은 문자열에서 분리자로 사용된 공백들을 전부 '\0'인 NULL 값으로 바꾸어주게 됩니다.(C언어에서 문자열 배열의 끝은 항상 \0입니다.) 


char형 포인터인 token에는 'I'가 위치한 주소가 들어가게 되고 token을 출력해보면 'I'가 나오는 것을 확인할 수 있습니다. 다음 두 번째를 실행된 배열을 확인하기 전에 주의사항으로는 "strtok(NULL, " ");"을 실행해야한다는 것입니다.


I

0

h

a

v

e

0

a

n

 

a

p

p

l

e

0


두 번째로 실행된 결과로 '\0'의 갯수가 2개로 늘어난 것을 볼 수 있고 token에는 'h'의 주소가 입력되어서 출력하면 'have'가 나오게 됩니다. 근데 왜 "strtok(s, " ");"이 아니라 "strtok(NULL, " ");"을 실행하라고 했을까요? 그 이유는 전자의 문장을 계속 실행해주면 'I' 밖에 출력되지 않기 때문입니다. 

strtok 함수는 맨 처음에 입력받은 문자열로 실행하고 나면 분리자가 위치한 주소의 다음 지점의 주소를 기억하게 되는데 문자열 배열인 's'를 입력하게 되면 기억한 주소는 날라가고 첫 번째 분리자를 찾는 과정만 계속 되풀이하게 되는 것입니다. 여기서 다음 지점의 주소는 'h'가 되겠네요.

I

0

h

a

v

e

0

a

n

0

a

p

p

l

e

0


다음은 세 번째로 실행된 결과로 공백이었던 공간 모두가 '\0'으로 뒤바뀌어 버렸습니다. 이번에 token에 대입되는 주소는 'a'가 위치한 주소이고요. 이어서 바로 네 번째로 실행해보면 문자열 배열 's'의 값은 세 번째에 실행된 결과와 동일한 모습입니다. 앞으로 공백이 없기 때문에 이상으로 끝날 것 같지만 'strtok' 함수는 검사해야 할 문자열이 없을 경우에 과정을 마무리하여서 token에 'apple'의 'a'가 위치한 주소를 반환시킵니다.


그 다음에 이제는 검사할 문자열이 없으므로 token은 NULL 값을 가지게 되고 문장을 이루는 단어들이 모두 분리된 것을 확인할 수 있습니다. 그럼 위에 설명한 과정을 코드로 한번 표현하여서 실행시켜보도록 하겠습니다.



저는 main 함수 밖에 기준 문자열이 될 문장을 문자열 배열인 's'와 분리된 단어들을 저장하는 역할을 하는 포인터 변수 'token'을 정의하였고 while 반복문에서 token에 마지막에 실행되어 반환되는 NULL 값이 있는지를 조건을 삼아서 코드를 짜보았습니다.



위의 사진이 그 결과로 제가 원했듯이 단어들이 차례대로 잘 실행된 것을 확인할 수 있었습니다. 이상으로 문자열 함수 strtok편을 마치도록 하겠고 다음에는 포인터 편을 포스팅 해볼까 합니다.

반응형
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
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 30 31
글 보관함