strtok 함수는 문자열을 구분문자(delimiter) 단위로 쪼개는데 사용되는데 이렇게 쪼개진 문자열을 토큰(token)이라고 한다.
str에 쪼개고자 하는 문자열을 전달하면 str의 가장 첫번째 문자가 토큰의 시작이 되고 delim에 포함된 문자들 중 하나를 만나는 곳이 토큰의 마지막이 되며, 원래 delimiter가 있었던 토큰의 마지막을 null-terminted 하고 토큰의 시작 주소를 리턴한다.
strtok 함수는 내부에 static 변수로 str 문자열에서 작업을 끝낸 다음 위치를 기억하고 있기 때문에,
이 다음에 str인자로 NULL을 전달하며 호출하면 이전에 찾았던 토큰 바로 다음 문자부터 시작해서 분리작업을 진행한다.
그러다 맨처음에 전달된 str 문자열의 NULL 문자에 도달하게 되면 이 후 str인자로 NULL이 전달되는 모든 호출에서 NULL포인터를 리턴하게 된다.
나중에 str인자로 다른 문자열을 전달하면 그 문자열로 토큰 분리작업을 하게 될 것이다.
#include <string.h>
char *strtok(char *str, const char *delim);
파라미터
- str : delimiter 단위로 분리할 문자열, 이 값이 NULL 이면 static 변수에서 저장하고 있던 이전 호출에서 작업한 그 다음 위치부터 분리작업을 진행한다. (원본 문자열을 보존하려면 임시변수에 복사해 전달해야한다.)
- delim : 문자열을 분리할 delimiter 들. 이중 하나라도 만나면 분리한다.
리턴값
- NULL 이 아닌값 : 정상적으로 분리하였고, 분리된 토큰의 시작 포인터를 리턴한다.
- NULL : 더이상 분리할 데이터가 없다.
#include <string.h>
#include <stdio.h>
/* /또는 - 또는 : 또는 space를 delimiter로 사용합니다. */
#define DELIM_CHARS "/-: "
int main(int argc, char **argv)
{
char time[1024] = "2023/01/15 20:29:30";
char *ptr;
printf("time : %s\n", time);
ptr = strtok(time, DELIM_CHARS);
while(ptr) {
printf("ptr = %s\n", ptr);
ptr = strtok(NULL, DELIM_CHARS);
}
return 0;
}
출처 : https://www.it-note.kr/85
strtok 함수는 내부에 static 변수를 사용하므로 multi-thread에 safe하지 않아서 대신 strtok_r 함수를 사용할 것이 권장된다.
사용법은 같으나, 다음 처리를 위한 위치를 저장하는 포인터로 내부 static 변수를 사용하는 대신 외부변수를 쓰게끔 하였다.
#include <string.h>
char *strtok_r(char *str, const char *delim, char **saveptr);
#include <string.h>
#include <stdio.h>
/* /또는 - 또는 : 또는 space를 delimiter로 사용합니다. */
#define DELIM_CHARS "/-: "
int main(int argc, char **argv)
{
char time[1024] = "2023/01/15 20:29:30";
char *ptr;
char *next_ptr;
printf("time : %s\n", time);
ptr = strtok_r(time, DELIM_CHARS, &next_ptr);
while(ptr) {
printf("ptr = %s\n", ptr);
ptr = strtok_r(NULL, DELIM_CHARS, &next_ptr);
}
return 0;
}
strtok_r 함수
char *
__strtok_r (char *s, const char *delim, char **save_ptr)
{
char *end;
if (s == NULL)
s = *save_ptr;
if (*s == '\0')
{
*save_ptr = s;
return NULL;
}
/* Scan leading delimiters. */
s += strspn (s, delim);
if (*s == '\0')
{
*save_ptr = s;
return NULL;
}
/* Find the end of the token. */
end = s + strcspn (s, delim);
if (*end == '\0')
{
*save_ptr = end;
return s;
}
/* Terminate the token and make *SAVE_PTR point past it. */
*end = '\0';
*save_ptr = end + 1;
return s;
}
Reference :
https://jybaek.tistory.com/593
'프로그래밍 > C' 카테고리의 다른 글
C ] sscanf() 사용법 (0) | 2023.01.15 |
---|---|
C ] strtol, strtoul : 정수 문자열을 진수 선택하여 long/unsigned long 값으로 변환 (2진수, 8진수, 10진수, 16진수) (0) | 2023.01.15 |
윈도우 소켓 ] 소켓 프로그래밍 용어 및 함수 정리 (0) | 2023.01.01 |
윈도우 소켓 ] TCP 에코 서버, 클라이언트 및 동작원리 (0) | 2023.01.01 |
윈도우 소켓 ] UDP 서버, 클라이언트 (0) | 2022.12.27 |