2012-12-25 2 views
-5

char 배열에 대한 포인터를 가져 와서 사용자로부터 문자열을 읽고 문자열이 아닌 첫 번째 문자가 나타날 때까지 문자열 시작 부분의 모든 공백을 제거하려고했습니다. 마지막으로 공백없이 문자열의 복사본을 반환합니다. abcd 입력 문자열 abcd 포인터를 리턴한다 함수의 예strtok이 예상대로 작동하지 않습니다.

,

.

입력 123 123의 경우 함수는 문자열 123 123에 대한 포인터를 반환해야합니다. 이 기능은 다음과 같습니다

,

void read_RemoveSpace(char * str)/**read the rest of string**/ 
{ 
    char tempRead[30]; 
    fgets(tempRead,30,stdin); 
    char *ptr = strtok(tempRead, " "); /**remove spaces between command and other data**/ 
    strcpy(str,ptr); /**copy the new string without the spaces.**/ 
} 

그러나 예상대로 기능 strtok()가 작동하지 않는 몇 가지 이유. 입력의 경우

:

123 456 

함수는 공백없이 첫 번째 부분을 리턴 아닌 문자열의 나머지, 즉 그것은

123 

어떤 제안이 가리키는?

+0

** 귀하의 ** 질문 ** !? – StoryTeller

+0

당신이 직면하고있는 문제는 무엇입니까? 어떻게 함수를 호출하고 있습니까? 정확히 str에 저장된 후 저장되는 것은 무엇입니까? – Vijay

+0

'strtok_r()'이 예상대로 작동하지 않습니다. 아마도 여러분의 기대치가 맞지 않을 것입니다 ... –

답변

4

strtok은 예상대로 정확하게 작동합니다. 문자열을 123456 문자열로 분리합니다.

strtok (tempRead, " "); /* Returns 123 */ 
strtok (NULL, " "); /* Returns 456 */ 

난 당신이 간단한 해결책으로 할 수 있다고 생각 : 예상대로 정확하게 작동하고

int i = 0; 
char tempRead[30]; 
... 
while (tempRead[i] == ' ' && tempRead[i]) 
    i++; 
strcpy(str,tempRead+i); 
2

.

strtok에 대한 첫 번째 호출은 토큰의 첫 번째 항목을 반환합니다. 후속 호출은 첫 번째 매개 변수를 NULL로 제공하는 경우 한 번에 하나씩 나머지 토큰을 반환합니다. strtok은 토큰이 부족할 때 NULL을 반환합니다.

편집 :
몇 가지 이상한 버그가 발생할 수있는, 그래서 그 사람 페이지를 언급 ​​무엇 strtok를 사용할 때 항상 염두에 두어야 여기에서 인용 :이 기능을 사용하는 경우

하는 것은주의해야합니다. 당신이 그들을 사용한다면,주의 :

  • 이 함수는 처음 인자를 수정한다.

  • 이 함수는 상수 문자열에 사용할 수 없습니다.

  • 구분 문자의 ID는 유실됩니다.

  • strtok() 함수는 구문 분석 중에 정적 버퍼를 사용하므로 스레드 안전하지 않습니다. 이 점이 중요 할 경우 strtok_r()을 사용하십시오.

0

strtok()를 사용하면 그것을 할 수있는 확실한 방법은 없습니다. 개행 포함 str으로 tempRead

void read_RemoveSpace(char *str) 
{ 
    char *dst = str; 
    char tempRead[30]; 
    if (fgets(tempRead, sizeof(tempRead), stdin) != 0) 
    { 
     char *src = tempRead; 
     char c; 
     while ((c = *src++) != '\0') 
     { 
      if (c != ' ') 
       *dst++ = c; 
     } 
    } 
    *dst = '\0'; 
} 

이 복사 비 블랭크; 원하는 경우 isspace() 또는 isblank()부터 #include <ctype.h>까지 사용할 수 있습니다. 나는 30이 로컬 스트링의 길이가 적당하다는 것을 확신하지 못하지만, 당신이 그 질문에 가지고있는 것입니다. 인터페이스에서 문자열이 제공되는 크기를 지정해야합니다 (void *read_RemoveSpace(char *buffer, size_t buflen)). 또한 함수가 문자열 끝에 null 포인터를 리턴 할 수 있습니다 (간접적으로 문자열의 길이에서 공백을 뺀 값).

void read_RemoveSpace(char *buffer, size_t buflen) 
{ 
    char *dst = buffer; 
    char tempRead[buflen]; 
    if (fgets(tempRead, sizeof(tempRead), stdin) != 0) 
    { 
     char *src = tempRead; 
     char c; 
     while ((c = *src++) != '\0') 
     { 
      if (!isspace((unsigned char)c)) 
       *dst++ = c; 
     } 
    } 
    *dst = '\0'; 
    return dst; 
} 

별로 다르지 않지만 훨씬 안전합니다. C99의 일부인 로컬 VLA 가변 길이 배열을 사용합니다. 그것은 VLA를 포기하고 직접 대상 버퍼에 복사를 할 수있을 것입니다 : 첫 번째 공백까지

void read_RemoveSpace(char *buffer, size_t buflen) 
{ 
    char *dst = buffer; 
    if (fgets(buffer, buflen, stdin) != 0) 
    { 
     char *src = buffer; 
     char c; 
     while ((c = *src++) != '\0') 
     { 
      if (!isspace((unsigned char)c)) 
       *dst++ = c; 
     } 
    } 
    *dst = '\0'; 
    return dst; 
} 

이 복사는 어떤 조합입니다; 그 후 문자를 최종 위치로 복사합니다.

관련 문제