2017-08-25 18 views
-1

私はC言語を学んでおり、質問があります。この演習では、ダブル・ダッチと呼ばれるゲームをプログラミングして、ストリングで練習する方法を学ばなければなりません。私が遭遇した問題は、プログラムがforループ条件(最初のforループ)のために実行を停止することです。 strlen()関数は、メインとayInFrontOfConsonant関数で最初に文字列の長さを印刷するときにうまく動作しますが、なぜプログラムが機能しなくなったのかわかりません。 Xcodeでは、スレッド1:EXC_BAD_ACCESSというメッセージが表示されます。どんな助力も非常に感謝しています。なぜこのforループ条件でstrlen関数が機能しないのですか?

void ayInFrontOfConsonant(char *str) 
{ 
    char consonants[42] = { 'b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 
'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'v', 'w', 'x', 'y', 'z', 'B', 
'C', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 
'T', 'V', 'W', 'X', 'Y', 'Z'}; 


    int a=(int)strlen(str); 

    printf("\n Length of str in ay function: %d\n",a); 

    int i=0,j=0; 
    for(i=0;i<strlen(str);i++)  //problem is here 
    { 
     for(j=0;j<strlen(consonants);j++) 
     { 
      if(str[i]==consonants[j]) 
      { 
       //insertChar(str, 'a', i); 

      } 
     } 
    } 
} 

int main() 
{ 
    int a=0; 
    printf("** Welcome to the Double Dutch game **\n"); 
    char myString[36]; 
    printf("Please enter a string: "); 
    scanf("%[^\n]s", myString); 

    a=strlen(myString); 
    printf("Length of string in main: %d\n",a); 

    ayInFrontOfConsonant(myString); 


    printf("Double dutch traslation: %s\n",myString); 


    return 0; 

}

+0

入力内容は何ですか? –

+0

私が使用する入力は: "私はCコードを書くのが好きです" –

+0

'strlen()'が何をしているのか分かっていれば、そのように使うことはできません。 –

答えて

3

あなたの配列にはnullターミネータを持っていません。その代わりの

sizeof *consonantsが確実1であるので、この特定の場合においてsizeof consonants/sizeof *consonants —またはを使用し、単にsizeof consonants

あなたが

const char *consonant = "bcdf ..."; 
を使用している場合、それはあなたの

char consonants[42] = { 'b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 
    'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'v', 'w', 'x', 'y', 'z', 'B', 
    'C', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 
    'T', 'V', 'W', 'X', 'Y', 'Z'}; 

に欠けているnullターミネータを検出するまで、それは、文字列を毎回横断ので、あなたは、forループの状態でstrlen()を使うべきではありません

の代わりに、'\0'ターミネータを追加します。明示的に追加することもできます。

彼らは並べ替えることができ、あなたが バイナリ検索を使用することができますので、子音の配列全体をスキャンする必要がないため
char consonants[] = { 'b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 
     'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'v', 'w', 'x', 'y', 'z', 'B', 
     'C', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 
     'T', 'V', 'W', 'X', 'Y', 'Z', '\0'}; 

プログラマはおそらく、代わりに

#include <stdlib.h> 

void ayInFrontOfConsonant(char *str) 
{ 
    char consonants[] = { 
     'b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 
     'p', 'q', 'r', 's', 't', 'v', 'w', 'x', 'y', 'z', 'B', 
     'C', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 
     'Q', 'R', 'S', 'T', 'V', 'W', 'X', 'Y', 'Z' 
    }; 

    for (size_t i = 0; str[i] != '\0'; i++) { 
     for (size_t j = 0; j < sizeof consonants; ++j) { 
      if (str[i] == consonants[j]) { 
       // Do here whatever you wanted to do 
      } 
     } 
    } 
} 

ではなく、実際にこれを書きますアルゴリズムを多く改良するだろう。あなたはchar consonants [42] = { ... }のような文を書く

+0

'sizeof(constonants)/ sizeof(* constonant)'の手法は、constonantsが配列の場合にのみ動作することに注意してください。それを関数の引数として渡すと、ポインタに変換され、テクニックは機能しません(長さを別の方法で渡す必要があります)。 – Peter

2

すると、3つのいずれかが起こる:

あなたが43個の以上の文字を持っている場合、コンパイラはあなたにエラーが発生します。

文字数が41文字以下の場合、コンパイラは配列の残りの部分を0で埋め込み、strlen()は文字の後にヌルバイトがあるため動作します。

正確に42文字の場合、コンパイラは配列を最後まで正確に埋めます。末尾のゼロバイトはありません。 strlenは機能しません。

実際には、文字数をカウントする理由はありませんでした。

char consonants [] = "bcdfgh..." 

は、あなたが望むものとまったく同じです。

+0

Re *はあなたが望むものを正確に*行うでしょう。もっと良い解決策は実際には配列を保持することですが、 'strlen'の代わりに' sizeof'を使います。 – ikegami

関連する問題