2017-08-10 6 views
0

私はまだCでプログラミングするのが初めてです。申し訳ありませんが、この種の質問が既に尋ねられている場合は、正確に何を検索するのか本当にわかりませんでした。このポインタ配列要素にNULL値を代入できないのはなぜですか?

練習として、私は辞書をプログラミングしています。この段階では、ユーザーは単語を追加、印刷、削除することができます。単語は 'dict'と呼ばれる文字ポインタ配列に格納されます。関数 'removeWord'は、削除される単語が配列 'dict'の最後の単語に置き換えられていることを確認する必要があります。したがって、最後の単語を削除する必要がある要素にコピーし、最後の要素を削除する必要があります(つまり、NULLに値を割り当てます)。削除される単語が配列 'dict'の最後の単語である場合は削除する必要があります。

アレイの最後のものを除いて、配列 'dict'内の単語が削除されると、プログラムは実行を停止します。最後のものを除いた単語が削除されたら、最後の要素に値NULLを割り当てたいと思います。

私の質問がはっきりしていることを願っています。私は本当にあなたが提供できるヘルプに感謝します。

int numberOfWordsInDict(char **dict) 
{ 
    int i,cnt=0; 
    for(i=0;i<10;i++) 
    { 
     if(dict[i]!=NULL) 
     { 
      cnt++; 
     } 
    } 
    return cnt; 
} 

void addWord(char **dict, char *word) 
{ 
    int i=0; 
    if(numberOfWordsInDict(dict)==10) 
    { 
     printf("Dictionary is already full!\n"); 
    } 
    int k=numberOfWordsInDict(dict); 
    dict[k]=(char*)malloc((strlen(word)+1)*sizeof(char)); 

    strcpy(dict[k],word); 
} 


void printDict(char **dict) 
{ 
    int i=0; 
    printf("Dictionary:\n"); 
    if(numberOfWordsInDict(dict)==0) 
    { 
     printf("The dictionary is empty.\n"); 

    }else 
    { 
     for(i=0;i<10;i++) 
     { 
     printf("- %s\n", dict[i]); 
     } 
    } 
} 

void removeWord(char **dict, char *word) 
{ 
    int i,j=0; 
    int swapped=0; 
    j=numberOfWordsInDict(dict); 
    for(i=0;i<j;i++) 
    { 
     if(strcmp(dict[i],word)==0 && swapped==0) 
     { 
     swapped=1; 
     //strcpy(dict[i],dict[j-1]); 
     dict[j-1] = NULL; 
     } 
    } 

} 

at dict [j-1]エラーが発生します。

int main() 
{ 
    char wordToBeAdded[36]={}; 
    char wordToBeRemoved[36]={}; 
    char *dict[10]={}; 
    char operation; 

    while(1) 
    { 
     printf("Command (a/p/r/q): "); 
     scanf(" %c", &operation); 

     switch(operation) 
     { 
      case 'a': 
       printf("Add a word: "); 
       scanf(" %s", &wordToBeAdded); 
       addWord(dict,wordToBeAdded); 
       break; 

      case 'p': 
       printDict(dict); 
       break; 

      case 'r': 
       printf("Remove a word: "); 
       scanf(" %s", &wordToBeRemoved); 
       removeWord(dict,wordToBeRemoved); 
       break; 

      case 'q': 
       return 0; 
     } 
    } 
} 
+1

クリスチャン・デLeijer何のエラーがありますか? –

+0

* dict [j-1]でエラーが発生します。 – lurker

+0

そのコードのために、プログラムは動作しなくなります。実際にはエラーはありません。 –

答えて

1

あなたの辞書の最後の項目が削除された後にアクセスすることが問題です。 dictの最後の項目にアクセスして単語と比較すると、すでにnullに設定されています。 Weather Vaneがコメントしたように、あなたがその言葉を見つけたら、あなたは壊れるかもしれません。これにより、削除されたときにこの最後のアイテムにアクセスできなくなります。私はJ-1 if(strcmp(dict[i],word)==0 && swapped==0)を=とき

void removeWord(char **dict, char *word) 
{ 
    int i,j=0; 
    int swapped=0; 
    j=numberOfWordsInDict(dict); 
    for(i=0;i<j;i++) 
    { 
     if(strcmp(dict[i],word)==0 && swapped==0) 
     { 
      swapped=1; 
      //strcpy(dict[i],dict[j-1]); 
      dict[j-1] = NULL; 
     } 
    } 

} 

だから、これはあなただけでnullに設定ポインタ間接参照しようとします。

+0

さて、問題は、strcmp()を使用することによってNULL値を持つポインタを逆参照しようとしていることです。 これについてはまだ1つの質問です。なぜ次のコードはコンパイル時にエラーを出さないのですか? int main() { char * dict [10] = {}; char * word = "hello"; strcmp(dict [1]、word); } –

+0

わかりましたので、私はちょうどあなたがstrcmpの値を使用しようとか、文などあればそれを入れているとき、コードがエラーを与えるこのコードを使用することによって判明... のint main()の { int a、b、c = 0; char * dict [10] = {}; char * word = "hello"; char * word2 = "bla"; char * word3 = "hello"; a = strcmp(word、word2); b = strcmp(word、word3); c = strcmp(dict [2]、word); printf( "\ n%d \ n"、a); printf( "\ n%d \ n"、b); printf( "\ n%d \ n"、c); } –

+0

私は今それを理解しています。私はこのフォーラムの初心者です。これらのコメントにコードを正しく入れる方法はわかりません(申し訳ありません)。あなたの助けをありがとう! –

-1

問題は、テーブルを反復して、NULLの値でポインタから読み取ろうとするときです。

最後の単語を削除すると、そこには決して行きません。しかし、テーブルを反復処理するときに最後のテーブルを削除しないと、テーブルを逆参照します。

私はあなたのコードのロジック(およびそれがどのような関数名を約束しているかどうかを確認していない)を変更するつもりはない - それはNULL

void printDict(char **dict) 
{ 
    int i=0; 
    printf("Dictionary:\n"); 
    if(numberOfWordsInDict(dict)==0) 
    { 
     printf("The dictionary is empty.\n"); 

    }else 
    { 
     for(i=0;i<10;i++) 
     { 
     if(dict[i] != NULL) printf("- %s\n", dict[i]); 
     } 
    } 
} 


void removeWord(char **dict, char *word) 
{ 
    int i,j=0; 
    int swapped=0; 
    j=numberOfWordsInDict(dict); 
    for(i=0;i<j;i++) 
    { 
     if(dict[i] != NULL) 
      if(strcmp(dict[i],word)==0 && swapped==0) 
      { 
      swapped=1; 
      //strcpy(dict[i],dict[j-1]); 
      free(dict[j-1]; 
      dict[j-1] = NULL; 
     } 
    } 

} 
でない場合だけチェックを追加することにより、ポインタの使用をサニタイズ
+0

コメントはありませんサイレントdownvoters? –

+0

私はそうではありませんが、コメントアウトされた行は 'dict [i] = dict [j-1];'であり、 'swapped'ではなく' break; '? –

+0

@Weather Vaneは答えの始めを見ます**機能が何をすべきかをチェックしません**、例のアプローチとしてUBを削除しました。彼はプログラミングを学んでいます - 自分自身のロジックでエラーを見つけようとします –

0

あなたのコードでは、変数jの値を決して変更しないので、最後のポインタをNULLに設定するだけです。これは、文字列リストから特定の項目を削除することではありません。

これ以外にも、削除された単語のスペースが解放されませんでした。また

、あなたのコードは、ソフトウェア工学の範囲に悪いです、必要があります。

  • は、このようなどこにでも値を書き込むの代わりに#define DICT_MAX_SIZE 10として、1つの同じ場所に定数を収集します。
  • 明確にその機能を発揮することができ、より良い選択肢があるようi j kとしてませ使用無意味な変数名、などdict_sizei_headi_tail、など。
+0

最後のポインタがNULLに設定されている理由はわかりません。なぜなら、dict内の単語の1つが削除すべき単語と等しい場合にのみ発生するからです。はい、あなたは正しいです、私のコードはソフトウェア工学に悪いです。私は電気工学を学びます。今のところ私はこのプログラムを働かせたいだけです。お返事をありがとうございます。 –

関連する問題