2016-05-05 2 views
-1

私は2つの文字列の間に共通の単語を印刷するプログラムを書いていました。さて、私は2つのループを使用し、それらの2つのループでこれらの文字列を分割します。しかし、必要な結果を得られなかった。その後、プログラムを少し変更してから、その外側ループが1回だけ実行されることを調べました。理由を知ることができませんでしたか?誰も考えられない?Cでstrtokの奇妙な行動?

#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

'(のstrcmp(TAR1、TAR2))' ...確かならば?一致がある場合、 'if'はFALSEになります... –

+2

' strtok'を2つの異なる文字列で同時に使用することはできません。私は 'strtok_s'または' strtok_r'のどちらかが利用可能であることをお勧めします。それでも、あなたはあなたが望む入れ子ループではなく、各文字列を1回だけ解析することができます。最初に配列にトークンポインタを抽出し、ネストされたループ検索を実行する必要があります。 –

+1

分割して配列に格納し、ループします。 strtokファミリーが文字列を変更するためです。 – BLUEPIXY

答えて

1

はstrtok()関数破断ゼロ以上 空でないトークンのシーケンスに文字列。すなわち

' 'strtokによってNUL(0)に置き換えられます。

したがって、tar2 = strtok(str2," ");を同じ文字列で2回使用することはできません。

@WeatherVaneによって指摘されているように:strtokを同時に2つの異なる文字列に使用することはできません。

あなたのコードの代わりに:

#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; 
} 

出力:あなたは同時に2つの異なる文字列にstrtokを使用することはできません、あなたがするので、複数回文字列を解析することはできません

Australia 
France 
2

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私はトップに私のコメントで、質問の下でそれを言及した。しかし、文字列をトークン化できるのは1回だけなので、比較する前にトークン化することもできます。 –