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

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

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

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

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

Q&A

解決済

1回答

1544閲覧

関数を複数使用した二分探索のプログラムについて教えていただきたいです。

tkgoisii

総合スコア2

C

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

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

0グッド

0クリップ

投稿2023/07/16 08:49

編集2023/07/16 15:06

ファイルから数値のデータを読み取る関数
数値のデータを選択ソートして昇順にする関数
二分探索する関数
これらを使ったプログラム

前提

ファイルから数値のデータを読み取り、二分探索するプログラムを「ファイルからデータを読み込む」「データの整列」「二分探索」の3つの関数を使用してプログラムを作成したいのですが、どの数値を探索しても-1を返されます。コンパイルはできますが、コアダンプが出ていてどこを直せばいいのかが分かりません。

該当のソースコード

c言語で、関数に分けてみたプログラムです。

#include <stdio.h> #include <stdlib.h> #define MAXDATA 10000 int fileopen(int a[MAXDATA]){ char filename[20]; FILE *fin; int n; printf("file name = "); scanf("%s", filename); if ((fin=fopen(filename, "r"))==NULL) { printf("ファイルをオープンできません\n"); return (-1); } n=0; while (fscanf(fin, "%d", &a[n])==1) n++; fclose(fin); return n; } void sort(int a[MAXDATA], int n){ int i, j, k; int tmp; int max; for (i = 0; i < n-1; i++) { j = i; for (k = i+1; k < n; k++) { if (a[j] > a[k]) { j = k; } } tmp = a[j]; a[j] = a[i]; a[i] = tmp; } for (i = 0; i < n; i++) { printf("%d\n", a[i]); } max = i; } int binarysearch(int n, int x, int a[MAXDATA]){ int min = 0; int mid; int i = 0; int position; int max = n-1; while (position==-1 && i<n) { mid = (max+min)/2; if (a[mid]==x) position=mid+1; else if (a[mid] < x){ min = mid+1; i++; } else if (a[mid] > x){ max = mid-1; i++; } } return position; } int main(void){ int a[MAXDATA]; int n; int x; int position; int max; n = fileopen(&a[MAXDATA]); max = n; sort(&a[MAXDATA], n); while (scanf("%d", &x)==1) { position=-1; binarysearch(n, x, &a[MAXDATA]); printf(" x=%d ---> %d\n", x, position); } printf("またお会いしましょう\n"); return 0; }

試したこと

binarysearchの部分をいじってみましたが、どこを変えればきちんと位置の値が出るのか分かりませんでした。ソートは昇順にはなるのですが、一部数値がおかしくなります。

補足情報(FW/ツールのバージョンなど)

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

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

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

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

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

jimbe

2023/07/16 09:22 編集

コードのファイル全体を一つの「コードのマークダウン」(```だけの行で前後を挟む)に入れるようにしてください。 また、 teratail はまずご自身で考えてやってみたことをご提示頂くのが基本的な事です。 https://teratail.com/help/question-tips 「やってみたけど出来なかったのでやめた」では、何を間違ったのか分かりません。結果的に丸投げになってしまいます。 とりあえずファイルの読み込みを別関数にしてみた状態を試したことにご提示してみては如何でしょう。
episteme

2023/07/16 11:29

> うまくできず困っています。 なにが/どう うまくできないのかの説明を。 「具合が悪い」の一言で薬をくれる医者はいません。
y_waiwai

2023/07/16 12:36

このままではコードが読めないので、質問を編集し、</>(コードの挿入)ボタンを押し、出てくる’’’の枠の中にコードを貼り付けてください
guest

回答1

0

ベストアンサー

色々いじったらコンパイルでエラーが多く出た

コンパイルエラーが出たなら、何が悪いのかを探して直さなければなりません。
一気に全てを変更からコンパイルしたのではどこで何が悪いのか探すのが面倒になります。
少し変更してコンパイルしエラーがあったらエラーだけを追及して直しコンパイルエラーが無くなったら動かして変更を確認する…のを繰り返す必要があります。
大量に修正してイッパツでコンパイルエラーも無く思った通りに動作させられることは滅多にありません。

配列の引数の書き方が分かっておられないようです。
配列の引数は先頭アドレスの受け渡しになります。そして、配列は配列名だけで先頭アドレスを表します。
int a[MAXDATA]a だけで先頭アドレスになりますので、file(&a[MAXDATA], n);file(a, n); と書かなくてはなりません。
関数側はアドレスを貰うのですから int file(int a[MAXDATA], int n){ では無く int file(int *a, int n){ とポインタになります。

また、関数の名前は基本的に動詞にしたほうが良いです。 file() という関数はファイルをどうするのか分かりませんが、 read() なら何かを読むらしいとか、もっとはっきり readFromFile() という名前ならファイルから読む関数であることが明白になります。

file 関数の第二引数 n は何の為にあるのでしょうか。もし n も file 関数から返すデータとするつもりなら、こちらもアドレス(とポインタ)にする必要があります。
引数の変数に値を設定しても呼び出し側の変数の値は変わりません
file(&a[MAXDATA], n);file(a, &n);
int file(int a[MAXDATA], int n){int file(int *a, int *n){
file 関数内では n がポインタになったため、 n を全て *n にする必要があります。(n=0;*n=0; 等)
ですが、コードを見れば file 関数は return n; としているので呼び出し側は関数値として n を得ることが出来ますから、いっそ第二引数 n は無くしたほうが簡単でしょう。
file(&a[MAXDATA], n);n=file(a);
int file(int a[MAXDATA], int n){int file(int *a){
これなら file 関数内で n を *n にする必要はありません。
ただし・・・file 関数では ファイルのオープンに失敗した場合も return 1; としているので、これでは1件正常に読めた場合と区別が付きません。
オープンに失敗した場合は(正常に読めた場合にはあり得ない) -1 を返すようにしたほうが良いでしょう。

sort 関数の第三引数 max も file 関数の n と同じでしょうか。
sort 関数は int 型の返り値が無ければならないのに return 文がありません。第三引数を無くして return i; でしょうか。 でも i は n と同じ値です。返す意味があるでしょうか。
・・・恐らく、検索の方の処理を見る限りは必要無いでしょうね。sort 関数を void 型にして return 文は無しで良いと思います。

binary 関数の第一引数 potision も、引数から削除して関数値でしょう。第三引数 max は削除、関数内で int max = n-1; を追加すれば良いでしょう。
binary 関数は search 関数と名前を変えたほうが良いと思います。


c

1#include <stdio.h> 2#include <stdlib.h> 3#define MAXDATA 10000 4 5//データをファイルから読み込む 6//a: データを格納する配列 7//関数値: 配列に格納した件数 8int readFromFile(int *a) { 9 char filename[20]; 10 printf("file name = "); 11 scanf("%s", filename); 12 13 FILE *fin = fopen(filename, "r"); 14 if(fin == NULL) { 15 printf("ファイルをオープンできません\n"); 16 return -1; 17 } 18 19 int n = 0; 20 while(fscanf(fin, "%d", &a[n]) == 1) n++; 21 22 fclose(fin); 23 24 return n; 25} 26 27//昇順に並び替える 28//a: データ配列 29//n: 配列内の有効件数 30void sort(int *a, int n) { 31 for(int i = 0; i < n - 1; i++) { 32 int j = i; 33 for(int k = i + 1; k < n; k++) { 34 if(a[j] > a[k]) { 35 j = k; 36 } 37 } 38 int tmp = a[j]; 39 a[j] = a[i]; 40 a[i] = tmp; 41 } 42 for(int i = 0; i < n; i++) { 43 printf("%d\n", a[i]); 44 } 45} 46 47//データを検索する 48//a: 昇順のデータ配列 49//n: 配列内の有効件数 50//x: 探すデータ 51//関数値: データが見つかったら配列のインデックスを返す. 無かったら -1 を返す 52int search(int *a, int n, int x) { 53 int min = 0; //最小値のインデックス 54 int max = n - 1; //最大値のインデックス 55 56 while(min <= max) { 57 int mid = (max + min) / 2; 58 if(a[mid] == x) return mid; 59 60 if(a[mid] < x) { 61 min = mid + 1; 62 } else { 63 max = mid - 1; 64 } 65 } 66 return -1; 67} 68 69int main(void) { 70 int a[MAXDATA]; 71 int n = readFromFile(a); 72 if(n < 0) exit(1); //オープンでエラーなら終わる必要がある 73 74 sort(a, n); 75 76 int x; 77 while(scanf("%d", &x) == 1) { 78 int position = search(a, n, x); 79 printf(" x=%d ---> %d\n", x, position); 80 } 81 82 printf("またお会いしましょう\n"); 83 return 0; 84}

投稿2023/07/16 13:41

編集2023/07/16 17:54
jimbe

総合スコア13318

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

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

tkgoisii

2023/07/16 15:19

本当にありがとうございます!貴方のおかげで解決しました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.31%

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

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

質問する

関連した質問