1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #include <stdio.h> #include <string.h> #include <stdlib.h> int main() { char str[] = "there#is#no#spoonnn"; char delim[] = "#"; char *token; token = strtok(str, delim); while (token != NULL) { printf("%s : %d\n", token, strlen(token)); token = strtok(NULL, delim); } return 0; } | cs |
나도 빨리 해보고 싶다~ 해서 F5를 눌렀지만,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #include <stdio.h> #include <string.h> #include <stdlib.h> int main() { char str[] = "there#is#no#spoonnn"; char delim[] = "#"; char *token, *context; token = strtok_s(str, delim, &context); while (token != NULL) { printf("%s : %d\n", token, strlen(token)); token = strtok_s(NULL, delim, &context); } return 0; } | cs |
what the... 나는 지금 visual studio를 쓰고 있어서 안된다. 하지만 #pragma 따위는 쓰지 않아!! 나는 겁이 많아서 시키는 대로 strtok_s를 쓸 것이다. 아래 함수 원형을 보자. delim이라는 것은 무엇을 기준으로 tokenizing을 할 것인가에 대한 문자열이다.
Defined in header <string.h> | ||
(1) | ||
char *strtok( char *str, const char *delim ); | (until C99) | |
char *strtok( char *restrict str, const char *restrict delim ); | (since C99) | |
char *strtok_s(char *restrict str, rsize_t *restrict strmax, const char *restrict delim, char **restrict ptr); | (2) | (since C11) |
아항, 마지막 char**이 하나 더 있구나!! 하면서 일단은 아래의 예제를 만들어봤다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #include <stdio.h> #include <string.h> #include <stdlib.h> int main() { char *str = "there#is#no#spoonnn"; char delim[] = "#"; char *token, *context; token = strtok_s(str, delim, &context); while (token != NULL) { printf("%s : %d\n", token, strlen(token)); token = strtok_s(NULL, delim, &context); } return 0; } | cs |
뭐야~~~ 또 안됨 ㅡ.ㅡ 뭐지 싶었는데 잘 보시라 char *str = "there#is#no#spoonnn"; 이 부분이 보이는가?
char *strtok_s(char *restrict str,,,); 그리고 이 부분도? 그렇다 문자열을 다룰 때 항상 조심해야 할 부분이 "리터럴"이다.
char *str = "there#is#no#spoonnn";
char str[] = "there#is#no#spoonnn";
이 둘의 차이라고도 할 수 있다. 사실 우리가 어떤 변수를 만든다고 생각하지만, 이는 착각이다. 이미 있는 것에 주소를 붙여서 마치 우리가 새로 만든 것 처럼 쓰는 것이다. 그래서 리터럴을 바꾸려고 하면 이는 노예가 주인을 거스르는 것이라고 할까나... 여하튼 불가능하다.(ㅠㅠ 설명이 너무 부족했다. 씹어먹는 C - 리터럴을 보시라.) 이를 위해 이 예제를 만든 것이다.
자, 다시 본론으로 돌아와서, 자세한 설명은 사실 나도 잘 못하지만, strtok함수는 그저 delim을 기준으로 자른 그 토막을 반환하고 strtok_s함수는 자르고 난 뒤의 남은 뭉텅이들을 context에 저장해준다는 정도라고 말할 수 있겠다. 사실 이 strtok계열 함수는 말이 많다고 한다. 아래의 그림을 보자.
strtok함수는 delim을 발견하면 \0을 껴넣어버린다. 문자열을 인식할 때 \0을 기준으로 삼는다는 것은 모두가 알 것이다. 그런데 strtok는 원본 문자열에 \0을 넣어버린다는 것이다. 이것 때문에 말이 많다고 한 것 같다. 주로 ' ' white space를 delim으로 많이들 삼는데 참고로 ' '이렇게 tab과 같이 겹쳐서 나와도 잘 걸러 준다. 우리는 그 논쟁에 끼지 말고 일단은 잘 쓰면 된다.
'개발' 카테고리의 다른 글
C언어 - save && load 예제 (0) | 2019.02.04 |
---|---|
C 언어 파일 입출력 시 한글 깨짐 문제 (7) | 2019.02.04 |
C 언어 - 자주 사용하는 함수 read_line (0) | 2019.01.10 |
C 언어 - strdup / _strdup (0) | 2019.01.10 |
C 언어 도서 관리 프로젝트 (0) | 2019.01.05 |