2016-05-05 3 views
-1

Я писал программу, в которой я хочу печатать общие слова между двумя строками. Ну, я использую две петли и разделяю эти строки в этих двух циклах. Но не получило необходимого результата. Затем я немного изменил программу, а затем исследовал, что внешний цикл выполняется только один раз. Не понял, почему? Кто-нибудь есть идея?Странное поведение strtok в C?

#include<stdio.h> 
#include<string.h> 
#include<stdlib.h> 
int main() 
{ 
    char str1[] = "Japan Korea Spain Germany Australia France "; 
    char str2[] = "England USA Russia Italy Australia India Nepal France"; 
    char *tar1 = strtok(str1," "); 
    char *tar2 = NULL; 
    while(tar1) 
    { 
     tar2 = strtok(str2," "); 
     while(tar2) 
     { 
      if(strcmp(tar1,tar2)) printf("%s %s\n",tar1 , tar2); 
      tar2 = strtok(NULL," "); 
     } 
     tar1 = strtok(NULL," "); 
     tar2 = NULL; 
    } 
    return 0; 
} 
+0

'если (зЬгстр (tar1, tar2))' ... уверен? в случае, если существует совпадение, 'if' будет FALSE ... –

+2

Вы не можете использовать' strtok' в двух разных строках одновременно. Я предлагаю 'strtok_s' или' strtok_r' в зависимости от того, что доступно. Даже тогда вы можете анализировать каждую строку только один раз, а не в вложенном цикле, на который вы надеетесь. Сначала необходимо извлечь указатели маркеров в массивы, а затем выполнить поиск вложенных циклов. –

+1

сплит для хранения в массивы, затем цикл. потому что семья strtok изменит строку. – BLUEPIXY

ответ

1

Функция strtok() перерывы строку в последовательность из нуля или более непустых маркеров.

Другими словами: ' ' заменяется NUL (0) от strtok.

В результате вы не можете использовать tar2 = strtok(str2," "); дважды с той же строкой.

И как указано @WeatherVane: Вы не можете использовать strtok на двух разных строках одновременно.

Альтернативой код:

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

int main(void) 
{ 
    char str1[] = "Japan Korea Spain Germany Australia France "; 
    char str2[] = "England USA Russia Italy Australia India Nepal France"; 
    char *tar = strtok(str1, " "); 
    char *ptr; 
    size_t sz; 

    while (tar) { 
     if ((ptr = strstr(str2, tar)) != NULL) { 
      /* First string or starts with " " */ 
      if ((ptr == str2) || (*(ptr -1) == ' ')) { 
       sz = strlen(tar); 
       /* Last string or ends with " " */ 
       if ((*(ptr + sz) == ' ') || (*(ptr + sz) == '\0')) { 
        puts(tar); 
       } 
      } 
     } 
     tar = strtok(NULL, " "); 
    } 
    return 0; 
} 

Выход:

Australia 
France 
2

Вы не можете использовать strtok на двух разных строк в то же время, и вы не можете разобрать строку несколько раз, потому что strtok уже модифицировал строку, разбив ее на nul терминаторы.

В этом примере извлекаются указатели маркеров в массив указателей для каждой входной строки перед проверкой совпадений.

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

#define MAXSTR 20 
int main() 
{ 
    char str1[] = "Japan Korea Spain Germany Australia France "; 
    char str2[] = "England USA Russia Italy Australia India Nepal France"; 
    char *tar1[MAXSTR]; 
    char *tar2[MAXSTR]; 
    char *tok; 
    int ind1 = 0, ind2 = 0; 
    int i, j; 

    tok = strtok(str1, " \t"); 
    while(tok != NULL && ind1 < MAXSTR) { 
     tar1[ind1++] = tok; 
     tok = strtok(NULL, " \t"); 
    } 

    tok = strtok(str2, " \t"); 
    while(tok != NULL && ind2 < MAXSTR) { 
     tar2[ind2++] = tok; 
     tok = strtok(NULL, " \t"); 
    } 

    for(i=0; i<ind1; i++) { 
     for(j=0; j<ind2; j++) { 
      if(strcmp(tar1[i], tar2[j]) == 0) { 
       printf("%s\n", tar1[i]); 
       break; 
      } 
     } 
    } 
    return 0; 
} 

выход программы:

Australia 
France 
+0

Возможно упоминать 'strtok_r', это может помочь. – phoxis

+1

@phoxis Я упомянул, что в моем комментарии наверху, по вопросу. Тем не менее, вы можете только токенизировать строку один раз, поэтому также можете их разграничить до сравнения. –

Смежные вопросы