ページ 11

学校の課題 文字配列

Posted: 2021年7月13日(火) 12:56
by こた
文字配列の課題でつまづいております。
名前を入力し、すでにある4人の名前と一致するかを確認し返す、という課題です。
同じ名前を入力しても、「その人はいません」と返されます。
以下のコードのどこが悪いのか、教えていただけないでしょうか。
全くの初心者ですので、どうぞよろしくお願いいたします!

コード:

#include<stdio.h>

int main(int argc, char *argv[]) {
  char input[9], string[4][9] = {"ヒロシ", "サトシ", "アキコ", "ユウコ"};
  int i, j, result = 0;
  while(1){
    printf("メンバー:ヒロシ,サトシ,アキコ,ユウコ\n");
    printf("名前を入力してください:");
    scanf("%s", input);
    for (i = 0; i < 4; i++){
      for (j = 0; j < 9; j++){       
        if(input[i] != string[i][j]){
          break;
        }
        else if(input[i] == '\0' && string[i][j] == '\0'){
          result = 1;
          i = 4;
          j = 9;
        }
      }
    }
    if (result == 1){
      printf("%sはメンバにいます.\n", input);
    }
    else {
      printf("%sはメンバにはいません.\n", input);
    }
  }
  return 0;
}
 

Re: 学校の課題 文字配列

Posted: 2021年7月13日(火) 17:51
by yoko
プログラム実行していないのですが、
for文内、

コード:

input[i]
の添え字のiがjなのでは?

Re: 学校の課題 文字配列

Posted: 2021年7月13日(火) 21:51
by こた
ご返信ありがとうございます!
ただ、for文内のinputをinput[j]に変えてみましたが、やはり合致している名前を入力しても「メンバではありません」になってしまいます。。ほかに考えられることがあればぜひ教えていただけると嬉しいです!

Re: 学校の課題 文字配列

Posted: 2021年7月13日(火) 22:39
by box
文字列を比較するための標準関数
strcmp()
を使う、というのは禁止されているのですか?
もし使ってよいのであれば、無理に自作するよりは
よほど安定した結果が得られると思うのですが...。

Re: 学校の課題 文字配列

Posted: 2021年7月13日(火) 22:41
by box
仮に禁止されているとしても、
strcmp 自作
とか
C言語 文字列比較 自作
とかのキーワードでググってみると、
実装のサンプルがいくらでも見つかると思います。

Re: 学校の課題 文字配列

Posted: 2021年7月14日(水) 00:57
by box
とりあえず無限ループはいらないと思いますので、やめときましょう。

コード:

#include <stdio.h>

int main(void)
{
    char input[9], string[][9] = { "ヒロシ", "サトシ", "アキコ", "ユウコ" };
    int i, j, result = 0;

    printf("メンバー:ヒロシ,サトシ,アキコ,ユウコ\n");
    printf("名前を入力してください:");
    scanf("%s", input);
    for (i = 0; i < 4; i++) {
        for (j = 0; j < 9; j++) {
            if (input[j] != string[i][j]) {
                break;
            }
            else if (input[j] == '\0' && string[i][j] == '\0') {
                result = 1;
                i = 4;
                j = 9;
            }
        }
    }
    if (result == 1) {
        printf("%sはメンバにいます.\n", input);
    }
    else {
        printf("%sはメンバにはいません.\n", input);
    }
    return 0;
}

Re: 学校の課題 文字配列

Posted: 2021年7月14日(水) 07:45
by みけCAT
使っている文字コードは何ですか?
UTF-8の場合、カタカナは1文字を3バイトで表す(厳密には例外があるかも?)ので、
9要素しか無い配列を使うとNUL文字が入る場所がありません。
NUL文字があったときにのみ result = 1; を実行するようになっているので、
この場合9要素しか見ないのであればresultは1にはなりません。
また、inputが9要素しか無く、scanfで読み込む最大のバイト数
(NUL文字を入れるため、最大でバッファサイズより1少ない数に設定するべき)が設定されていないため、
バッファオーバーフローを起こしてまわりのデータを破壊する危険があります。

Re: 学校の課題 文字配列

Posted: 2021年7月14日(水) 16:52
by こた
box様、みけCAT様、お返事ありがとうございます!
box様、まだstrcmp関数は習っておらず、とりあえず配列とループ文のみ既習のため、それだけでなんとかしようと苦しんでおりました。教えて頂いた通り、ネットでも検索して勉強したいと思います!無限ループはずしました。
みけCAT様、ご指摘頂いた通り、まずは配列の要素数を9→20にしてみたところ、warningはでなくなりました!ただ、やはり同一の名前を入力してもメンバにはいません、と出てしまいます。。が、ネットでも同様のコードを探して勉強しようと思います。
お二人とも、お忙しいところありがとうございました!

Re: 学校の課題 文字配列

Posted: 2021年7月14日(水) 19:20
by みけCAT
配列の要素数だけでなく、jのループの上限も増やす必要があります。

Re: 学校の課題 文字配列

Posted: 2021年7月14日(水) 23:26
by こた
ご指摘ありがとうございます。うっかりしており、ループの上限20にしました。動いて感動しました!本当にありがとうございました!