2016-10-04 8 views
1

그래서 나는 같은 문자열을 주어진 해요 : 내가 말한거야예기치 않은 동작이 사용 strtok를

Hello6World66ABC 

는 문자의 단일 인스턴스를 대체 할 '6'이 개 asteric 문자 "**"

로 그리고 6의 여러 인스턴스가이 두 문자 중 하나가 될 수 있습니다. (행 번호 6의 모든 조합이 적용됩니다.) char *의 각 문자를 전달하여이 작업을 시도하고 있습니다. 6 문자, 다음 문자가 6인지 확인합니다. 그렇지 않은 경우 첫 번째 사례가 있고, 그렇지 않으면 두 번째 사례 (다중 6)가 있습니다.

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 

int main(void) { 
    char * str; 
    int i; 
    str = malloc(17); 

    strcpy(str,"Hello6World66ABC"); 

    for(i=0; i < strlen(str); i++) { 
     if(str[i] == '6') { 
      if(str[i+1] != '6') { 
       char * token = strtok(str,"6"); 
       strcpy(str,token); 
       strcat(str,"**"); 
       printf("String is now %s\n",str); 

       token = strtok(NULL,""); /*get the rest of the string*/ /* should be World66ABC */ 
       printf("Rest of the string is %s\n",token); 
       str = (char *) realloc(str,strlen(str) + strlen(token) + 1); 
       strcat(str,token); 
       printf("String is now %s\n",str); 
       /* should be Hello**World66ABC */ 
      } 
      else { 
       /*if the next characters are also (multiple ones in a row) 6's, replace it with two ^^ characters*/ 
       char * token = strtok(str,"6"); 
       token = strtok(NULL,"6"); 
       printf("TOKEN IS %s\n",token); 

       strcpy(str,token); 
       strcat(str,"^^"); 

       token = strtok(NULL,""); /*get the rest of the string*/ /* should be World66ABC */ 
       printf("Rest of the string is %s\n",token); 
       str = (char *) realloc(str,strlen(str) + strlen(token) + 1); 
       strcat(str,token); 
       printf("String is now %s\n",str); 


      } 
     } 
    } 

    free(str); 
    return 0; 
} 

주어진 문자열에 의해, 내 예상 최종 문자열은 다음과 같아야합니다

Hello**World^^ABC 

하지만, 내 strtok를 호출 내가 의도 한대로 작동하지 않습니다.

두 번째 if 문에서 if (str[i+1] != '6')을 확인하면 단 하나의 6이 있는지 확인합니다.

그때 나는 그것을 전에 strtok를 인쇄 모든 전화 : 가 인쇄 : 올바른 입니다 Hello**

내가 어떤 작품 그것에에 새로운 문자를 strcat와, 그러나 나의 두 번째 strtok를 호출에, 나머지를 얻을 수 문자열의, 그냥 작동하지 않습니다.

대신 인쇄 :

"Rest of the string is *" 

를 그래서 분명히 내가 빈 문자열로 구분 기호를 설정에도 불구하고, 문자열의 나머지 부분을 점점 아니에요.

구분 기호를 다른 문자로 변경하려고했지만 동일한 결과가 각각 나타납니다. 첫 번째 경우에는 문자열이 길어지기 때문에 다시 할당합니다. 또한 else 문은 절대로 실행되지 않는 것처럼 보입니다. 물론 여러 개의 6이있는 경우도 있습니다.

여기서 내가 잘못 생각한 부분이 있는지 모르겠다.

+4

나는'너무 확실하지 않다 strtok'도 여기에 작업에 적합한 도구입니다. –

+0

각 문자를 루핑하기 때문에'strtok '이 필요 없다는 것을 알았습니다 - 이미 6이 어디에 있는지 알고 있습니다. 또한 더 나은 옵션은 두 번째 문자열 버퍼를 만들어 새 문자열을 만드는 것입니다. –

+0

그래서, 정확히 ** 당신의 의견은 무엇입니까? 그리고 왜 'strtok'을 사용합니까? 또한 : 올바르게 읽으면 두 문자열을 원래 문자열에'strcat'합니다. 그 코드는 그 간단한 작업을 위해 불필요하게 날아간 것처럼 보입니다. @FredLarson이 맞습니다'strtok'는 잘못된 함수입니다. – Olaf

답변

1

이것은 테스트되지 않았지만 일반적인 아이디어를 보여줍니다.

strcpy(str,"Hello6World66ABC"); 

// New string will be at most 2x as long 
char *new_str = calloc(strlen(str) * 2 + 1, 1); 
int new_str_index = 0; 

for (int i = 0; 0 != str[i]; i++) { 
    // Check for 6 
    if ('6' == str[i]) { 
     // Check for 2nd 6 
     if ('6' == str[i+1]) { 
      // Add chars 
      new_str[new_str_index++] = '^'; 
      new_str[new_str_index++] = '^'; 
      // Consume remaining 6s - double check this for off-by-one 
      while ('6' == str[i+1]) i += 1; 
     } 
     else { 
      // Add chars 
      new_str[new_str_index++] = '*'; 
      new_str[new_str_index++] = '*'; 
     } 
    } 
    // No 6s, just append text 
    else { 
     new_str[new_str_index++] = str[i]; 
    } 
} 
+0

new_str을 원본 str에 복사하려면 realloc을 실행 한 다음 memmove()를 호출해야합니다. 중복을 피하시겠습니까? – efoekfoe

+0

예, 아니면 그냥 : free (str); str = strdup (new_str);'. –

+1

물론 원래 문자열이 재 할당 가능하다고 가정하십시오. 게시 된 코드의 경우가 아니라 문자열 리터럴에 대한 포인터 인 경우 성공적으로 재 할당 할 것으로 예상 할 수 없습니다. 가장 일반적인 해결책은 새 문자열에 대한 포인터를 반환하는 것입니다. –

1

OP는 문자열의 '6' 문자를 변경하는 간단한 방법을 요청했습니다. 직접 인쇄하는 대신 다른 문자열에 쓰고 싶다면 나머지 문자열 (충분히 큰 문자열)을 정의한 다음 stdout 대신 해당 문자열에 문자를 복사하십시오. 그러나 전달 된 문자열을 변경하려고 시도하지 마십시오. 실패 할 운명입니다.

#include <stdio.h> 

void sixer(char *str) 
{ 
    int i = 0, sixes; 
    while(str[i] != '\0') { 
     if(str[i] == '6') { 
      sixes = 0; 
      while(str[i] == '6') { 
       sixes++; 
       i++; 
      } 
      if(sixes == 1) { 
       printf("**"); 
      } 
      else { 
       printf("^^"); 
      } 
     } 
     else { 
      printf("%c", str[i]); 
      i++; 
     } 
    } 
    printf("\n"); 
} 

int main(void) 
{ 
    sixer("Hello6World66ABC"); 
    sixer("6"); 
    sixer("66666"); 
    return 0; 
} 

프로그램 출력

Hello**World^^ABC 
** 
^^