質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

1回答

689閲覧

C言語 関数に配列を渡せない

退会済みユーザー

退会済みユーザー

総合スコア0

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2022/05/02 18:54

C

1// コードは一部省略しています. 完全版は一番下にあります. 2 3B_H check(const char ans[], const char num[]) { 4 printf("ans %s\n", ans); // check 1 5 printf("num %s\n", num); // check 2 6} 7 8int main(void) { 9 char ans[DIG]; 10 char num[DIG]; 11 12 create_num(ans); // ans[i]に数字文字('0'~'9')を代入 i=0~DIG 13 printf("%s\n", ans); // main 1 14 while (bh.hit != DIG) { 15 scanf("%s", num); 16 bh = check(ans, num); // main 2 17 } 18 return 0; 19}

main関数内の// main 1ではcreate_num関数で代入した数字文字の文字列が正しく表示されますが,//main 2で配列ansをcheck関数へ渡そうとしても,正常に渡せません.
すなわち//check 1の部分が表示されません("ans "と空白になる).
一方,//check 2の部分では,numの値ーmain関数のwhile文内のscanfで入力した値ーが正しく表示されます.

どうして,配列ansを関数checkへ正しく渡せていないのですか?
ご回答のほどよろしくお願いします.

なお,実行環境はmacOS 10.15のApple clang version 12.0.0 (clang-1200.0.32.29)です.

C

1// 完全版 2#include <stdio.h> 3#include <stdlib.h> 4#include <string.h> 5#include <ctype.h> 6#include <limits.h> 7#include <time.h> 8 9#define DIG 4 10 11typedef struct { 12 int blow; 13 int hit; 14} B_H; 15 16int sleep(unsigned long x) { 17 clock_t c1 = clock(), c2; 18 do { 19 if ( (c2 = clock()) == (clock_t)-1) return -1; 20 } while (1000.0*(c2-c1) / CLOCKS_PER_SEC < x); 21 return 1; 22} 23 24int create_num(char ans[]) { 25 int r; 26 int i = 1; 27 int flag = 1; 28 srand(time(NULL)); 29 if (DIG > 9) return -1; 30 ans[0] = (rand() % 10) + '0'; 31 while (i < DIG) { 32 flag = 1; 33 ans[i] = (rand() % 10) + '0'; 34 for (int j = 0; j < i; j++) { 35 if (ans[j] == ans[i]) { 36 flag = 0; 37 break; 38 } 39 } 40 if (flag) i++; 41 } 42 return 1; 43} 44 45B_H check(const char ans[], const char num[]) { 46 B_H bh; 47 bh.blow = 0; 48 bh.hit = 0; 49 printf("ans %s\n", ans); 50 printf("num %s\n", num); 51 for (int i = 0; i < DIG; i++) { 52 for (int j = 0; j < DIG; j++) { 53 if (ans[i] == num[j]) { 54 bh.blow++; 55 if (i == j) bh.hit++; 56 break; 57 } 58 } 59 } 60 printf("blow%d\nhit%d\n", bh.blow,bh.hit); 61 return bh; 62} 63 64int put(B_H bh) { 65 putchar('\n'); 66 if (bh.hit == DIG) { 67 puts("正解!"); 68 return 1; 69 } 70 else if (bh.blow == 0) 71 puts("どの数字も含まれません."); 72 else { 73 printf("それらの数字中%d個の数字が含まれます.\n", bh.blow); 74 if (bh.hit) printf("その中の%d個は位置もあっています.\n", bh.hit); 75 else puts("ただし位置もあっている数字はありません."); 76 } 77 return 0; 78} 79 80 81int main(void) { 82 char ans[DIG]; 83 char num[DIG]; 84 B_H bh; 85 bh.blow = 0; 86 bh.hit = 0; 87 int n = 0; 88 int cnt; 89 create_num(ans); 90 printf("%s\n", ans); 91 while (bh.hit != DIG) { 92 printf("\n重複のない%d桁の数字を当ててください : ", DIG); 93 scanf("%s", num); 94 bh = check(ans, num); 95 put(bh); 96 } 97 return 0; 98}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

配列ansを関数checkへ正しく渡せていないのではなく、関数checkを呼び出す前の時点で配列ansの中身が破壊されているのではないでしょうか。

C言語の文字列の末尾には、ヌル文字'\0'を追加する必要があるので、4文字の文字列を保存するためには、長さ5の文字配列が必要となります。
しかし、現状numの長さが4しかないので、scanfで4文字の文字列を読み込んだ際に、範囲外の5番目の位置に'\0'を書き込んでしまいます。
今回は、たまたまその範囲外にあるのがansだったので、ansの先頭がヌル文字'\0'に書き換わって、長さ0の文字列になってしまったものと思われます。

修正するには、char num[DIG];char num[DIG+1];に変更してみてください。

投稿2022/05/02 20:45

編集2022/05/02 22:54
actorbug

総合スコア2224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2022/05/03 01:41

ご回答ありがとうございます.ご指摘の通りに直したら正しく動作しました. ヌル文字のことをすっかり忘れていました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問