c언어 strtok 함수는 구분자들을 받으면, 문자열을 토큰으로 나누는 함수입니다. 어떻게 사용하는지 간단하게 알아보도록 합시다.
원형은 아래와 같습니다.
- 리턴값
- 토큰의 시작 주소
- 토큰이 없다면 NULL을 돌려줍니다.
- str
- 토큰화 할 문자열을 의미합니다.
- NULL을 넘기면 다음 토큰의 시작 주소를 리턴합니다.
- delimeters
- 구분자들을 의미합니다.
처음에 문자열의 시작 주소를 넘기면, 1번째 토큰 끝 부분을 NULL로 바꿉니다. 원본을 변형시킨다는 점을 반드시 조심해야 해요.
먼저 예제 1번 프로그램을 보겠습니다. “abc def ghi”라는 문자열이 있습니다. 그리고, strtok의 1번째 인자로 str을, 2번째 인자로 ” “을 넘겨주었습니다. 공백 문자만 구분자로 받았다는 의미입니다. 다음에 p는 strtok의 리턴값을 받습니다.
실행 결과를 볼까요? 보았더니, “abc”가 리턴됩니다. 어떻게 된 일일까요?
원래 str은 이렇게 있었습니다. 4번째 위치에 공백 문자가 있습니다.
이 공백 문자를 만나는 순간 NULL로 바꾸어 버립니다.
- 토큰을 찾았습니다. abc입니다.
- 토큰이 끝나는 위치가 군청색 부분이니, 이 위치를 NULL로 바꿉니다.
리턴하는 값은 토큰 “abc”의 시작을 가리키는 p입니다.
예제 2번 프로그램은 어떨까요? 이번에는 abc 앞에 공백이 다수 있습니다. 이 경우도 크게 어렵지 않습니다. 토큰이 시작하는 위치는 어디인가요?
3번째 위치입니다. 토큰이 끝나는 위치는 군청색으로 칠해진 6번째 부분입니다. 따라서, 6번째 부분은 NULL을 채워 넣습니다. 그리고, strtok은 p가 가리키는 위치를 리턴합니다.
마찬가지로 abc가 리턴됩니다.
1번째 인자에 NULL을 넘기면 어떤 일이 일어날까요?
- 이전에 strtok를 불렀을 때 성공한 위치부터 탐색
하게 됩니다. 즉, strtok에서 공용 변수를 쓰고 있다는 이야기가 됩니다. 잘못 사용하면 끝없는 디버그 지옥에 빠지는 원인이 되기도 합니다. ps 할 때는 strtok 쓰지 말고 string 으로 변환해서 처리하는 게 더 합리적일 정도입니다.
예제 3번 프로그램을 보겠습니다. 1번째 printf문은 어렵지 않게 “abc”가 나올 것이라는 것을 예상할 수 있습니다. 2번째가 문제인데요. NULL을 1번째 인자로 넘겨줬단 말입니다.
그러면 pos 다음인 7번째부터 탐색하게 됩니다. 보니까, 토큰 def가 나오고, 공백이 나왔네요. f 뒤에 위치는 NULL로 바꿉니다. 따라서, 그 다음 토큰인 “def”가 시작하는 위치가 리턴됩니다.
결과는 위와 같습니다.
쓸만한 C언어 strtok 함수 예제
이제, 예제 2개를 보겠습니다. 먼저, 공백을 기준으로 구분하는 것입니다.
예제 4번 프로그램입니다. strtok 함수를 쓸 때 공식처럼 쓰게 되는 것이니 외우시면 좋습니다.
- 먼저, 토큰으로 분리할 문자열 str과 구분자를 strtok으로 넘겨줍니다. [6번째 줄]
- 이 함수의 리턴 값을 p라 하겠습니다.
- while 문으로 strtok의 리턴 값 p가 NULL이 아닐 때 까지 계속 strtok을 할 거에요. [7번째 줄]
- while loop 안에서 strtok를 계속 써 주시면 되는데요.
- 다른 점은 strtok의 1번째 인자에 NULL을 넘겨줘야 한다는 점입니다.
결과를 볼까요?
결과는 abc, def, ghi;abc가 나옵니다.
이제, 구분자가 여러개인 경우는 어떻게 하면 좋을까요? 간단합니다. delimeters에 구분자로 쓸 것들을 넘겨주면 됩니다. 저는 “:,;”을 넘겨주었는데요. :과 ,와 ;를 구분자로 하겠다는 의미입니다.
예제 5번 프로그램을 실행시키면 abc, def, ghi, abc가 나오게 됩니다.