2009-03-23 4 views
4

저는 strtok의 자체 버전을 개발했습니다. 포인터 사용법을 연습하기 만하면됩니다.strtok 대안을 개발했습니다

누구나이 제한 사항을 볼 수 있습니까? 어쨌든 개선 할 수 있습니까?

void stvstrtok(const char *source, char *dest, const char token) 
{ 
    /* Search for the token. */ 
    int i = 0; 
    while(*source) 
    { 
     *dest++ = *source++; 
     if(*source == token) 
     { 
      source++; 
     } 
    } 
    *dest++ = '\0'; 
    } 

int main(void) 
{ 
    char *long_name = "dog,sat ,on ,the,rug,in ,front,of,the,fire"; 
    char buffer[sizeof(long_name)/sizeof(*long_name)]; 

    stvstrtok(long_name, buffer, ','); 

    printf("buffer: %s\n", buffer); 

    getchar(); 

    return 0; 
} 
+0

strtok에서 다음 토큰을 반환해야하지만이 코드는 구분 기호 만 제거합니다. – Vinay

+0

'\ 0'이 누락 된 결함있는 문자열을 보내고 어떤 일이 발생하는지 확인하려면 이 코드가 NULL 또는 임의의 문자열을 어떻게 처리합니까? – Johan

답변

7

사이드 노트 : '토큰'이라는 단어는 대개 반환되는 문자열 부분을 설명하는 데 사용됩니다. 구분 기호는 토큰을 구분하는 것을 설명하는 데 사용됩니다. 그래서 코드를 좀 더 명확히하기 위해 토큰의 이름을 구분 기호로 변경하고 dest의 이름을 token_dest로 변경해야합니다. 함수 및 strtok를에

차이 : 당신의 기능과 strtok를 사이에 몇 가지 차이가 ​​있습니다

.

  • 함수는 단순히 토큰 구분
  • 을 제거한다 무엇을 당신은 문자열의 모든 부분을 처리하기 위해 한 번 함수를 호출합니다. strtok를 사용하면 문자열의 각 부분에 대해 여러 번 호출 할 수 있습니다 (첫 번째 매개 변수로 NULL이 포함 된 후속 시간).
  • strtok도 소스 문자열을 파괴하지만 코드는 자체 버퍼를 사용합니다 (내가했던 것처럼 자신의 버퍼를 사용하는 것이 좋습니다).
  • strtok은 첫 번째 매개 변수가 NULL 인 각 호출 후에 다음 토큰의 위치를 ​​저장합니다. 이 위치는 후속 호출에 사용됩니다. 이것은 쓰레드에 안전하지 않으며 함수는 쓰레드에 안전합니다.
  • strtok에서는 여러 개의 다른 구분 기호를 사용할 수 있지만 코드는 하나만 사용합니다.

말하자면, strtok의 구현에 더 가까운 함수가 아닌 더 나은 함수를 만드는 방법에 대한 제안을하겠다.

당신의 기능을 개선하는 방법 (strtok를 에뮬레이트하지 않음) :

을 나는 다음과 같이 변경하기 위해 더 좋을 거라 생각 :

  • 가지고 함수는 단순히 '다음'토큰
  • 을 반환을
  • * source 또는 * source == 구분 기호가있는 경우 루프가 끊어집니다.
  • 다음 토큰을 포함하는 소스 문자열의 첫 문자를 가리키는 포인터를 반환하십시오. 이 포인터는 후속 호출에 사용될 수 있습니다.
1

strtok를 사용하면 모든 토큰을 반복 할 수 있습니다. 이것은 소스 문자열이 쓰기 가능하고 토큰 중단시 널 (NULL)을 삽입한다고 가정하여 수행합니다. 목적지 버퍼는 소스 버퍼가있는 문자 오프셋에 대한 포인터입니다. 이 사실을 사용하여 통화 종료 시점을 알 수 있으며 + 또한 통화간에 "상태"를 유지할 수 있습니다.

Strtok은 소스 문자열을 손상시키기 때문에 사용하기에 좋은 함수는 아닙니다. 또한 재진입하지 않습니다.

+0

재입국을위한 경우 : strtok_r() –

1

strtok()는 일부 상태를 저장하므로 여러 번 호출하여 여러 토큰을 얻을 수 있습니다. 또한 strtok()은 소스 문자열을 "분할"하여 여러 개의 대상 문자열을 얻습니다. 각 대상 문자열은 하나의 토큰이됩니다.

모든 코드는 내가 본 것으로부터 토큰 분리 자와 동일한 입력 문자를 무시하고 원본의 null 종결에 계속 복사합니다.

편집 : 또한 두 개의 시퀀싱 토큰 분리 자이 있다고 가정합니다. 첫 번째는 함수에서 무시되고 두 번째는 대상에 쓰여지지만 strtok()은 두 개 이상의 구분 기호로 구성된 연속을 단일 분리 문자 (설명서 페이지 : http://man.cx/?page=strtok)

3

이 코드는 전혀 작동하지 않습니다. strtok(). 정확히 무엇을하려 했습니까? 그러나 개선 사항까지 코드에 심각한 버그가 있습니다. token의 발생 횟수를 뺀 길이가 dest보다 큰 경우 자신이 매우 고전적인 스택 오버플로인데 다소 아이러니하게 보입니다 그 순간 나에게. 이것은 사용한 적이있는 main에서는 발생하지 않지만, 다른 곳에서이 함수를 사용하면 불확실성과 절망의 길로 인도 할 수 있습니다.

1

strtok은 입력 문자열을 NUL 문자로 파괴하여 적대적으로 만듭니다.

또한 "xyz ,, pdq"의 경우를 고려해야합니다. ','가 구분 기호 인 경우 strtok이 문자열에서 얼마나 많은 토큰을 꺼낼 것인지를 고려해야합니다.

이 경우 어떤 기능을 수행 하시겠습니까?

1

또한 strtok (...)은 여러 구분 문자를 지원합니다. strspn (...) 및 strcspn (...)의 정의를 살펴보면 strtok (...)을 다시 구현할 수 있습니다.

1

길에 따라 long_name은 char에 대한 포인터이고 sizeof (long_name)는 sizeof (char *)입니다. 은 long_name이 가리키는 크기가 아닙니다.