プロが教えるわが家の防犯対策術!

ファイル(1000.txt)から1000 個の数字を読み込んだ後,キーボードから入力した数字があ
る場所を再起関数search(配列 x のx[from] から x[to] の間からscannum の要素を探す関数)を使って出力するプログラムを作りたいのですがどうすればよいですか。

void search(int x[], int scannum, int from, int to){


int main(void) {
FILE *fp;
int i;
int x[1000], scannum, line;
if ((fp = fopen("1000.txt", "r")) == NULL) {
printf("can't open file\n");
return 0;
}
for (i = 0; i < 1000; i++) {
fscanf(fp, "%d", &x[i]);
}
scanf("%d", &scannum);
line = search(x, scannum, 0, 999);
printf("%d\n", line);
}

読み込むファイル以下のようなファイルです。
1000.txt
0
2
4
6
.....

A 回答 (3件)

#include <stdio.h>


#include <stdlib.h>

void search(int x[], int scannum, int from, int to);

int main(void) {
 FILE *fp;
 char s[4];
 int x[1000], scannum;
 if ((fp = fopen("1000.txt", "r")) == NULL) {
  puts("can't open file");
  return EXIT_FAILURE;
 }
 for (int i = 0; i < 1000; i++) {
  fscanf(fp, "%d", &x[i]);
 }
 scanf("%3s%*[^\n]*c",s);
 scannum = strtol(s, NULL, 10);
 search(x, scannum, 0, 999);
 return EXIT_SUCCESS;
}

void search(int x[], int scannum, int from, int to) {
 if (from > to) {
  puts("can't find scannum");
 } else if (x[from] == scannum) {
  printf("%d\n", from + 1);
 } else {
  search(x, scannum, from + 1, to);
 }
}
    • good
    • 0

あ、やべぇ。

ファイル閉じるの忘れてた。

main関数のreturn EXIT_SUCCESS;の前にfclose(fp);を付け加えておいて下さい。
    • good
    • 0
この回答へのお礼

参考にさせて頂きます!
main関数は変えずに作りたいのですがどうすれば良いですか

お礼日時:2021/06/07 15:00

> main関数は変えずに作りたいのですがどうすれば良いですか



基本的には無理です。
と言うのもsearch関数の定義に問題がある。

void search(int x[], int scannum, int from, int to)

と言う定義により、この関数には返り値がない。
コンピュータサイエンス用語で言うとこれ、つまりvoidを返り値とする関数は手続き(プロシージャ)と呼びます。こいつには返り値がない。
ところが、main関数内で

line = search(x, scannum, 0, 999);

とint型変数lineがsearchの返り値を受け取ってる。
これじゃあダメです。

ここを使いたいのなら、searchをintを返す関数として定義しなければなりません。

/* sample */

#include <stdio.h>
#include <stdlib.h>

int search(int x[], int scannum, int from, int to);

int main(void) {
 FILE *fp;
 char s[4];
 int x[1000], scannum, line;
 if ((fp = fopen("1000.txt", "r")) == NULL) {
  puts("can't open file");
  return EXIT_FAILURE;
 }
 for (int i = 0; i < 1000; i++) {
  fscanf(fp, "%d", &x[i]);
 }
 scanf("%3s%*[^\n]*c",s);
 scannum = strtol(s, NULL, 10);
 line = search(x, scannum, 0, 999);
 printf("%d\n", line);
 return EXIT_SUCCESS;
}

int search(int x[], int scannum, int from, int to) {
 if (from > to) {
  puts("can't find scannum");
  return EXIT_FAILURE;
 } else if (x[from] == scannum) {
  return from + 1;
 } else {
  return search(x, scannum, from + 1, to);
 }
}

/* ここまで */

他の変更点は、安全性の為、です。
scanfはそのまま無邪気に使うとバッファオーバーランの危険性があるので、なるたけ入力は文字列で受け取り、整数値に変換するようにした方が危険がありません。

scanfの問題点と回避方法:
https://ja.wikipedia.org/wiki/Scanf#scanf%E3%81% …

なるべく、こういったscanfの使い方を早い内に覚えておきましょう。
    • good
    • 0
この回答へのお礼

なるほど
丁寧な解説ありがどうございます!
勉強になりました!

お礼日時:2021/06/08 17:57

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!