[c] strtok ()는 C에서 문자열을 토큰으로 어떻게 분할합니까?

strtok()기능 작동에 대해 설명해주십시오 . 매뉴얼은 문자열을 토큰으로 나눕니다. 나는 그것이 실제로하는 일을 매뉴얼에서 이해할 수 없다.

에 나는 시계를 추가 str하고 *pch첫 While 루프가 발생했을 때의 작동을 확인의 내용은 str단지 “이”을했다. 아래에 표시된 출력이 화면에 어떻게 인쇄 되었습니까?

/* strtok example */
#include <stdio.h>
#include <string.h>

int main ()
{
  char str[] ="- This, a sample string.";
  char * pch;
  printf ("Splitting string \"%s\" into tokens:\n",str);
  pch = strtok (str," ,.-");
  while (pch != NULL)
  {
    printf ("%s\n",pch);
    pch = strtok (NULL, " ,.-");
  }
  return 0;
}

산출:

문자열 "-이것은 샘플 문자열입니다." 토큰으로 :
이
ㅏ
견본
끈



답변

strtok()문자열을 토큰으로 나눕니다. 즉, 구분자 중 하나에서 다음으로 시작하면 하나의 토큰이됩니다. 귀하의 경우 시작 토큰은 “-“에서 시작하고 다음 공백 “”으로 끝납니다. 다음 토큰은 “”에서 시작하여 “,”로 끝납니다. 여기서 “This”를 출력으로 얻습니다. 마찬가지로 나머지 문자열은 공백에서 공백으로 토큰으로 분할되고 마지막으로 “.”에서 마지막 토큰이 끝납니다.


답변

strtok 런타임 함수는 다음과 같이 작동합니다.

strtok를 처음 호출 할 때 토큰화할 문자열을 제공합니다.

char s[] = "this is a string";

위의 문자열 공간에서 단어 사이의 좋은 구분 기호로 보이므로 다음을 사용하십시오.

char* p = strtok(s, " ");

이제 일어나는 일은 공백 문자가 발견 될 때까지 ‘s’가 검색되고 첫 번째 토큰이 반환되고 ( ‘this’) p가 해당 토큰 (문자열)을 가리 킵니다.

다음 토큰을 얻고 동일한 문자열을 계속하려면 strtok가 이전에 전달 된 문자열에 대한 정적 포인터 를 유지하므로 NULL이 첫 번째 인수로 전달됩니다 .

p = strtok(NULL," ");

p는 이제 ‘is’를 가리 킵니다.

더 이상 공백을 찾을 수 없을 때까지 계속하면 마지막 문자열이 마지막 토큰 ‘문자열’로 반환됩니다.

더 편리하게 다음과 같이 작성하여 모든 토큰을 인쇄 할 수 있습니다.

for (char *p = strtok(s," "); p != NULL; p = strtok(NULL, " "))
{
  puts(p);
}

편집하다:

반환 된 값을 저장하려면 strtok토큰을 다른 버퍼에 복사해야합니다. 예를 들어 strdup(p);원래 문자열 (내부 정적 포인터가 가리키는 strtok)이 토큰을 반환하기 위해 반복 사이에 수정되기 때문입니다.


답변

strtok문자열에서 사용 가능한 다음 토큰을 가리키는 정적 내부 참조를 유지합니다. NULL 포인터를 전달하면 내부 참조에서 작동합니다.

이것이 strtok재진입이 아닌 이유 입니다. 새 포인터를 전달하자마자 이전 내부 참조가 손상됩니다.


답변

strtok매개 변수 자체를 변경하지 않습니다 ( str). 해당 포인터를 (지역 정적 변수에) 저장합니다. 그런 다음 매개 변수를 다시 전달하지 않고도 후속 호출에서 해당 매개 변수가 가리키는 것을 변경할 수 있습니다 . (그리고 그 포인터를 계속 진행시킬 수 있지만 작업을 수행해야합니다.)

POSIX strtok페이지에서 :

이 함수는 정적 저장소를 사용하여 호출 사이의 현재 문자열 위치를 추적합니다.

strtok_r이러한 유형의 마법을 수행하지 않는 스레드로부터 안전한 변형 ( )이 있습니다.


답변

처음 호출 할 때 토큰화할 문자열을 strtok. 그런 다음 다음 토큰을 얻으려면 NULLNULL포인터를 반환하는 한 해당 함수에 제공 하면 됩니다.

strtok함수는 호출 할 때 처음 제공 한 문자열을 기록합니다. (다중 스레드 응용 프로그램에는 정말 위험합니다)


답변

strtok는 문자열을 토큰 화합니다. 즉 일련의 하위 문자열로 변환합니다.

이러한 토큰 (또는 하위 문자열)을 구분하는 구분 기호를 검색하여이를 수행합니다. 그리고 구분자를 지정합니다. 귀하의 경우에는 ”또는 ‘,’또는 ‘.’를 원합니다. 또는 ‘-‘는 구분 기호입니다.

이러한 토큰을 추출하는 프로그래밍 모델은 기본 문자열과 구분 기호 집합을 strtok하는 것입니다. 그런 다음 반복적으로 호출하고 매번 strtok가 찾은 다음 토큰을 반환합니다. null을 반환 할 때 메인 문자열의 끝에 도달 할 때까지. 또 다른 규칙은 처음에만 문자열을 전달하고 이후에는 NULL을 전달하는 것입니다. 이것은 새 문자열로 토큰 화의 새 세션을 시작하거나 이전 토큰 화 세션에서 토큰을 검색하는 경우 strtok에 알리는 방법입니다. strtok는 토큰 화 세션의 상태를 기억합니다. 이러한 이유로 재진입 또는 스레드로부터 안전하지 않습니다 (대신 strtok_r을 사용해야합니다). 알아야 할 또 다른 사항은 실제로 원래 문자열을 수정한다는 것입니다. 찾은 구분 기호에 대해 ‘\ 0’을 씁니다.

strtok를 간단히 호출하는 한 가지 방법은 다음과 같습니다.

char str[] = "this, is the string - I want to parse";
char delim[] = " ,-";
char* token;

for (token = strtok(str, delim); token; token = strtok(NULL, delim))
{
    printf("token=%s\n", token);
}

결과:

this
is
the
string
I
want
to
parse


답변

strtok는 입력 문자열을 수정합니다. 원래 문자열의 비트를 토큰으로 반환하도록 null 문자 ( ‘\ 0’)를 그 안에 배치합니다. 사실 strtok는 메모리를 할당하지 않습니다. 일련의 상자로 문자열을 그리면 더 잘 이해할 수 있습니다.