関数を使ったコードについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
しき

関数を使ったコードについて

#1

投稿記事 by しき » 1年前

「ファイルからデータを読み込む」「データの整列」「二分探索」をそれぞれ関数と して構成したプログラムを作成せよ。ただし、関数 には、処理に必要なデータを引数として 渡すようにすること。

という問題が出てソースコードを書いてみたはいいのですがエラーがたくさん出てきてうまくコンパイルされません。
なにを変える、もしくは何を付け足したらうまくコンパイルできるようになるでしょうか。よろしくお願いします。

コード:

#include <stdio.h>
#include <stdlib.h>
#define MAXDATA 10000


char fileinput(char filename[20], int a[MAXDATA])
{

  int n;
  FILE *fin;

  if ((fin=fopen(filename,"r"))==NULL){
  return(1);
  }
  n=0;
  while(fscanf(fin, "%d", &a[n])==1) n++;
  fclose(fin);
  return n;
}

void selectionsort(int a[MAXDATA],int n )
{
  int i,j,k;
  int tmp;
  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;
  }
}

int bsearch(int x, int a[MAXDATA],int n)
{
  int min;
  int max;
  int mid;


    min=0;
    max=n;
    while(min <= max ) {
     mid = (min + max) / 2;
      if (a[mid]==x) {
        break;
      } else if (a[mid] < x) {
        min = mid + 1;
      } else if (a[mid] > x){
        max = mid - 1;
      }
    }
  }


int main(void)
{
  char filename[20];
  int n,x,y;
 int a[MAXDATA];
  int i;
  printf("ファイル名=");
  scanf("%s",filename);

  n=open(filename,a);
  if(n==1){
    printf("ファイルをオープンできません。\n");
  }
  else { selectionsort(i,n);

     printf("探したい値を入力してください:");
     scanf("%d",&x);
  y=a[bsearch(x,a,n)]
    if(x=y)
      printf(" x=%d ---> %d\n",a[bsearch(a,x,n)] );
   else
      puts("見つかりませんでした");
  return 0;
}

アバター
asd
記事: 301
登録日時: 8年前

Re: 関数を使ったコードについて

#2

投稿記事 by asd » 1年前

エラーメッセージが出るなら、それを提示しておくとよいと思います。
オフトピック
新しく質問をする前に過去の質問の終了処理をしておきましょう。
「解決しました!」ではどのように解決したのかわからないので、最終的なソースを提示いただければと思います。

http://dixq.net/forum/viewtopic.php?f=3&t=19423
http://dixq.net/forum/viewtopic.php?f=3&t=19425
Advanced Supporting Developer
無理やりこじつけ(ぉ

しき

Re: 関数を使ったコードについて

#3

投稿記事 by しき » 1年前

asdさん返信ありがとうございます

エラーメッセージはいかの通りになります
36:5: エラー: ‘bsearch’ と型が競合しています
int bsearch(int x, int a[MAXDATA],int n)
^
2:0: 備考: 前の ‘bsearch’ の宣言はここです
extern void *bsearch (const void *__key, const void *__base,
^
: 関数 ‘main’ 内:
:71:3: 警告: 1 番目の ‘selectionsort’ の引数へ渡すときに整数からキャスト無しにポインタを作成しています [デフォルトで有効]
else { selectionsort(i,n);
^
:21:6: 備考: expected ‘int *’ but argument is of type ‘int’
void selectionsort(int a[MAXDATA],int n )
^
:76:5: エラー: expected ‘;’ before ‘if’
if(x=y)
^
:78:5: エラー: ‘else’ の前に ‘if’ がありません
else
^
:81:1: エラー: expected declaration or statement at end of input
}

アバター
purin52002
記事: 235
登録日時: 1年前
連絡を取る:

Re: 関数を使ったコードについて

#4

投稿記事 by purin52002 » 1年前

こんにちは

36行目のbsearchという自作関数ですが、既存の関数名とかぶっているようです。
名前を変更するといいかもしれません。

71行目の selectionsortに渡している引数が多分おかしいです。

75行目の処理にセミコロンが抜けています。

閉じかっこ } の数が一致していないです。

というエラーが出ているようです。

最初のうちはエラーメッセージの意味がよくわからないと思いますが、
きちんと読んでみると大体エラーの理由がわかるようになりますよ^^
c++初心者を自負しています。
質問者さんには今後私にプログラミングを教えてくれるようにやさしく丁寧に教えるつもりです。ぎぶあんどていく^p^
回答者さんには精一杯感謝します。ぎぶおんりー^p^

しき

Re: 関数を使ったコードについて

#5

投稿記事 by しき » 1年前

purin52002さん返信ありがとうございます。
なるほどそういう意味だったんですね。
修正してみます。

しき

Re: 関数を使ったコードについて

#6

投稿記事 by しき » 1年前

修正してみました!
がまだエラーメッセージが絶えません。エラーメッセージは以下の通りになります。エラーメッセージの意味を教えてください。よろしくお願いします。
: 関数 ‘main’ 内:
:74:7: 警告: passing argument 1 番目の ‘binsearch’ の引数を渡すときにポインタからキャスト無しに整数を作成しています [デフォルトで有効]
printf(" x=%d ---> %d\n",a[binsearch(a,x,n)] );
^
:35:5: 備考: expected ‘int’ but argument is of type ‘int *’
int binsearch(int x, int a[DATA],int n)
^
:74:7: 警告: 2 番目の ‘binsearch’ の引数へ渡すときに整数からキャスト無しにポインタを作成しています [デフォルトで有効]
printf(" x=%d ---> %d\n",a[binsearch(a,x,n)] );
^
:35:5: 備考: expected ‘int *’ but argument is of type ‘int’
int binsearch(int x, int a[DATA],int n)
^

コード:

#include <stdio.h>
#include <stdlib.h>
#define DATA 10000

char fileinput(char filename[20], int a[DATA])
{

  int n;
  FILE *fin;

  if ((fin=fopen(filename,"r"))==NULL){
  return(1);
  }
  n=0;
  while(fscanf(fin, "%d", &a[n])==1) n++;
  fclose(fin);
  return n;
}

void selectionsort(int a[DATA],int n )
{
  int i,j,k;
  int tmp;
  for(i=0; i < n; i++){
    j=i;
    for(k=i+1; k < n+1; k++){
      if (a[j] > a[k]){ j=k; }
    }
    tmp=a[j];
    a[j]=a[i];
    a[i]=tmp;
  }
}

int binsearch(int x, int a[DATA],int n)
{
  int min;
  int max;
  int mid;

    min=0;
    max=n;
    while(min <= max ) {
      mid = (min + max) / 2;
      if(x < a[mid])
        max=mid-1;
      else if(x >a[mid])
        min=mid+1;
     else
        return mid;
    }
    return(1);
      }

int main(void)
{
  char filename[20];
  int n,x,y;
  int a[DATA];
  int i;
  printf("ファイル名=");
  scanf("%s",filename);
  n=open(filename,a);
if(n==1){
    printf("ファイルをオープンできません。\n");
  }
  else { selectionsort(a,n);

     printf("探したい値を入力してください:");
     scanf("%d",&x);
     y=a[binsearch(x,a,n)];
    if(x=y)
      printf(" x=%d ---> %d\n",a[binsearch(a,x,n)] );
    else
      puts("見つかりませんでした");
  return 0;
}
}


アバター
purin52002
記事: 235
登録日時: 1年前
連絡を取る:

Re: 関数を使ったコードについて

#7

投稿記事 by purin52002 » 1年前

:74:7: 警告: passing argument 1 番目の ‘binsearch’ の引数を渡すときにポインタからキャスト無しに整数を作成しています [デフォルトで有効]
printf(" x=%d ---> %d\n",a[binsearch(a,x,n)] );

キーワードは
”引数”、”ポインタ”
ですかね。

no3のエラーの中にも同じ種類のエラーがありました。
no4でエラーの解決法を書きました。

これらをヒントにしてみてください^^
c++初心者を自負しています。
質問者さんには今後私にプログラミングを教えてくれるようにやさしく丁寧に教えるつもりです。ぎぶあんどていく^p^
回答者さんには精一杯感謝します。ぎぶおんりー^p^

しき
記事: 34
登録日時: 1年前

Re: 関数を使ったコードについて

#8

投稿記事 by しき » 1年前

purin52002さん返信ありがとうございます。
無事コンパイルできました!
コンパイルはできたのですが・・ファイルからデータを入力する関数が動きません・・。これは関数に問題があるのでしょうか?それとも関数の呼び出しに問題があるのでしょうか?よろしくお願いします。

コード:


#include <stdio.h>
#include <stdlib.h>
#define DATA 10000

char fileinput(char filename[20], int a[DATA])
{

  int n;
  FILE *fin;

  if ((fin=fopen(filename,"r"))==NULL){
  return(1);
  }
  n=0;
  while(fscanf(fin, "%d", &a[n])==1) n++;
  fclose(fin);
  return n;
}//ファイルからデータを入力する関数

void selectionsort(int a[DATA],int n )
{
  int i,j,k;
  int tmp;
  for(i=0; i < n; i++){
    j=i;
    for(k=i+1; k < n+1; k++){
      if (a[j] > a[k]){ j=k; }
    }
    tmp=a[j];
    a[j]=a[i];
    a[i]=tmp;
  }
}//データを整列する関数

int binsearch(int x, int a[DATA],int n)
{
  int min;
  int max;
  int mid;

    min=0;
    max=n;
    while(min <= max ) {
      mid = (min + max) / 2;
      if(x < a[mid])
        max=mid-1;
      else if(x >a[mid])
        min=mid+1;
      else
        return mid;
    }
    return(1);
}//二分探索する関数

int main(void)
{
  char filename[20];
  int n,x,y;
  int a[DATA];
  int i;
  printf("ファイル名=");
  scanf("%s",filename);
  n=open(filename,a);
 if(n==1){
    printf("ファイルをオープンできません。\n");
  }
  else { selectionsort(a,n);

     printf("探したい値を入力してください:");
     scanf("%d",&x);
     y=a[binsearch(x,a,n)];
    if(x=y)
      printf(" x=%d ---> %d\n",a[binsearch(x,a,n)] );
    else
      puts("見つかりませんでした");
  return 0;
}
}


アバター
purin52002
記事: 235
登録日時: 1年前
連絡を取る:

Re: 関数を使ったコードについて

#9

投稿記事 by purin52002 » 1年前

気になる箇所がいくつかあります。

まずは13行目、 return(1) です。
今回読み込むファイルはデータ数が1ではないのかもしれませんが、
これではデータ数が1のデータを読み込んだ時に正しく読み込めたのか読み込めていないのかがわかりません。
返り値を変えたほうが個人的に好きです^^

次に16行目、 fscanf(fin, "%d", &a[n])==1 です。
これも個人的な意見ですが、fscanfの判定にはEOFを使った方が好きです^^

最後に64行目、 n=open(filename,a) です。
せっかく fileinput という関数を作ったのに 既存の open 関数を使っていいんでしょうか?
c++初心者を自負しています。
質問者さんには今後私にプログラミングを教えてくれるようにやさしく丁寧に教えるつもりです。ぎぶあんどていく^p^
回答者さんには精一杯感謝します。ぎぶおんりー^p^

しき
記事: 34
登録日時: 1年前

Re: 関数を使ったコードについて

#10

投稿記事 by しき » 1年前

purin52002さん返信ありがとうございます。
指摘されたところを修正してみました。
きちんとファイルからは読み込まれるようになりました。

しかしうまいこと実行結果が出てくれません・・。疑問なのは要素の位置が4の倍数で出ていること、また3桁の数字が正しく表示されないことです。またファイルを開いてそこからループさせようともしましたがこのループも「探したい値を入力してください」が1回だけ表示されてその後は実行結果の通りです・・。解決策を教えてください。よろしくお願いします。
ファイルの中身とファイル名はこれです-->wc.out{1,6,43,123,2}
-------------------------------------
ファイル名=wc.out
探したい値を入力してください:1
x=1 ---> 4
2
x=2 ---> 8
6
x=6 ---> 12
43
x=43 ---> 16
123
x=1 ---> 4
------------------------------------

コード:

#include <stdio.h>
#include <stdlib.h>
#define DATA 10000

char fileinput(char filename[20], int a[DATA])
{

  int n;
  FILE *fin;

  if ((fin=fopen(filename,"r"))==NULL){
  return(-1);
  }
  n=0;
  while(fscanf(fin, "%d", &a[n]) !=EOF) n++;
  fclose(fin);
  return n;
}//ファイルからデータを入力する関数

void selectionsort(int a[DATA],int n )
{
  int i,j,k;
  int tmp;
  for(i=0; i < n; i++){
    j=i;
    for(k=i+1; k < n+1; k++){
      if (a[j] > a[k]){ j=k; }
    }
    tmp=a[j];
    a[j]=a[i];
    a[i]=tmp;
  }
}//データを整列する関数

int binsearch(int x, int a[DATA],int n)
{
  int min;
  int max;
  int mid;
    min=0;
    max=n-1;
    while(min <= max ) {
      mid = (min + max) / 2;
      if(x < a[mid])
        max=mid-1;
      else if(x >a[mid])
        min=mid+1;
      else
        return mid;
    }
    return(1);
}//二分探索する関数

int main(void)
{
  char filename[20];
  int n,x,y;
  int a[DATA];
  int i;

  printf("ファイル名=");
  scanf("%s",filename);
  n=fileinput(filename,a);
   if(n==-1){
  printf("ファイルをオープンできません。\n");
  }
    else { selectionsort(a,n);
      while (scanf("%d", &x)==1) {
     printf("探したい値を入力してください:");
     scanf("%d",&x);
     y=a[binsearch(x,a,n)];

    if(x=y)
      printf(" x=%d ---> %d\n",a[binsearch(x,a,n)] );
    else
      puts("見つかりませんでした");
      }
}
   printf("またお会いしましょう\n");
 return 0;
}


アバター
purin52002
記事: 235
登録日時: 1年前
連絡を取る:

Re: 関数を使ったコードについて

#11

投稿記事 by purin52002 » 1年前

68行目の scanf==1 が個人的に好きじゃないです^p^
73行目のif文の判定式がおかしい気がします。
74行目でbinsearchを呼び出すのは無駄なような気がします。

アルゴリズムに関しては見るのがめんどくさいので自分で調べてみてください^p^
各変数の値をprintfなどで表示するとわかりやすいかもしれません^^
c++初心者を自負しています。
質問者さんには今後私にプログラミングを教えてくれるようにやさしく丁寧に教えるつもりです。ぎぶあんどていく^p^
回答者さんには精一杯感謝します。ぎぶおんりー^p^

しき
記事: 34
登録日時: 1年前

Re: 関数を使ったコードについて

#12

投稿記事 by しき » 1年前

purin52002さん返信ありがとうございます。
アドバイスありがとうございます。
アルゴリズムの件分かりました。自分で調べてみます・・・。

アバター
purin52002
記事: 235
登録日時: 1年前
連絡を取る:

Re: Opencv関連で発生するlnk2019エラーについて

#13

投稿記事 by purin52002 » 1年前

今実行して気が付いたこと

68行目のwhile分の判定式いらなくね?->69,70行目で同じことをもう一度するから
74行目の引数が足りない^p^->引数の数そろえたらちゃんと表示されました。
入力に123を入れると"見つかりませんでした"が表示される。->アルゴリズムがおかしい^p^
c++初心者を自負しています。
質問者さんには今後私にプログラミングを教えてくれるようにやさしく丁寧に教えるつもりです。ぎぶあんどていく^p^
回答者さんには精一杯感謝します。ぎぶおんりー^p^

しき
記事: 34
登録日時: 1年前

Re: 関数を使ったコードについて

#14

投稿記事 by しき » 1年前

purin52002さん返信ありがとうございます。
68行目の件了解です。
同じく引数の数お揃えたらいけました!
123の件も  max = n-1 を max =n に変えたらいけました!

しき
記事: 34
登録日時: 1年前

Re: 関数を使ったコードについて

#15

投稿記事 by しき » 1年前

できました!
アドバイスありがとうございました!
最終コードは以下のようになります。

コード:


#include <stdio.h>
#include <stdlib.h>
#define DATA 10000

char fileinput(char filename[20], int a[DATA])
{

  int n;
  FILE *fin;

  if ((fin=fopen(filename,"r"))==NULL){
  return(-1);
  }
  n=0;
  while(fscanf(fin, "%d", &a[n]) !=EOF) n++;
  fclose(fin);
  return n;
}//ファイルからデータを入力する関数

void selectionsort(int a[DATA],int n )
{
  int i,j,k;
  int tmp;
  for(i=0; i < n; i++){
    j=i;
    for(k=i+1; k < n+1; k++){
      if (a[j] > a[k]){ j=k; }
    }
    tmp=a[j];
    a[j]=a[i];
    a[i]=tmp;
  }
}//データを整列する関数

int binsearch(int x, int a[DATA],int n)
{
  int min;
  int max;
  int mid;

  while (scanf("%d", &x)==1) {
   min=0;
    max=n;
    while(min <= max ) {
      mid = (min + max) / 2;
      if (a[mid]==x) {
        break;
      } else if (a[mid] < x) {
        min = mid + 1;
      } else if (a[mid] > x){
       max = mid - 1;
      }
    }
    if(a[mid]==x){
      printf(" x=%d ---> %d\n",x ,mid-1 );

    }
    else {
      printf("見つかりませんでした。\n",x);
    }
  }
    return 0;
}//二分探索する関数

int main(void)
{
  char filename[20];
  int n,x,y;
  int a[DATA];


  printf("ファイル名=");
  scanf("%s",filename);
  n=fileinput(filename,a);
   if(n==-1){
    printf("ファイルをオープンできません。\n");
  }
    else {
      selectionsort(a,n);

      printf("探したい値を入力してください\n");
      y=a[binsearch(x,a,n)];

    }
   printf("またお会いしましょう\n");
   return (0);
}


かずま

Re: 関数を使ったコードについて

#16

投稿記事 by かずま » 1年前

しき さんが書きました:できました!
できていないと思います。

0 を探して「見つかりませんでした」と出ますか?

wc2.out というファイルで、-5 や -3 や 0 を探してみてください。

コード:

1 6 43 123 2 -5 -3
しき さんが書きました:最終コードは以下のようになります。
間違いは、次の 3個所です。どう直せばよいか、わかりますか?

コード:

    for(k=i+1; k < n+1; k++){

    max=n;

      printf(" x=%d ---> %d\n",x ,mid-1 );

しき
記事: 34
登録日時: 1年前

Re: 関数を使ったコードについて

#17

投稿記事 by しき » 1年前

かずまさん返信ありがとうございます。
0を探したとき「見つかりませんでした」とでません。0を探したときにはー1と出ました・・。
探した結果は以下のようになります

コード:

探したい値を入力してください
0
 x=0 ---> 1
-5
 x=-5 ---> -1
-3
 x=-3 ---> 0
一つ目は何が違うかわかりません・・
二つ目はn-1ですか?
三つ目は実行結果が
x=1 ---> 1
x=2 ---> 2
と出てうまくいかなかったので表示だけでも正確にとやってしまいました・・。
mid-1がmidです。

かずま

Re: 関数を使ったコードについて

#18

投稿記事 by かずま » 1年前

最初の質問(No.1)の selectionsort は正しいのに、
No.6 からおかしくなっています。

データが n個なら、a[0]~a[n-1] にデータが入っています。
k < n+1 だと k は n になって、a[n] にアクセスします。

binsearch で、max = n も範囲外です。

上記の修正をする前に、selectionsort の呼出しの前後に
次のようなデバッグ用の printf を入れてみてください。

コード:

    printf("n = %d\n", n);                          // for debug
    for (i = 0; i <= n; i++) printf(" %d", a[i]);   // for debug
    puts(" : before sorting");                      // for debug
    selectionsort(a, n);
    for (i = 0; i <= n; i++) printf(" %d", a[i]);   // for debug
    puts(" : after sorting");                       // for debug

しき
記事: 34
登録日時: 1年前

Re: 関数を使ったコードについて

#19

投稿記事 by しき » 1年前

入れてみました。
ファイルには入れていないはずの0があります・・・

コード:

1 6 43 123 2 -5 -3 0 : before sorting
 -5 -3 0 1 2 6 43 123 : after sorting
探したい値を入力してください

しき
記事: 34
登録日時: 1年前

Re: 関数を使ったコードについて

#20

投稿記事 by しき » 1年前

連投すみません
指摘されたところを直したらしっかり動くようになりました!
ありがとうございます!

コード:

#include <stdio.h>
#include <stdlib.h>
#define DATA 10000

char fileinput(char filename[20], int a[DATA])
{

  int n;
  FILE *fin;

  if ((fin=fopen(filename,"r"))==NULL){
  return(-1);
  }
  n=0;
  while(fscanf(fin, "%d", &a[n]) !=EOF) n++;
  fclose(fin);
  return n;
}//ファイルからデータを入力する関数

void selectionsort(int a[DATA],int n )
{
  int i,j,k;
  int tmp;
  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;
  }
}//データを整列する関数

int binsearch(int x, int a[DATA],int n)
{
  int min;
  int max;
  int mid;

  while (scanf("%d", &x)==1) {
   min=0;
    max=n;
    while(min <= max ) {
      mid = (min + max) / 2;
      if (a[mid]==x) {
        break;
      } else if (a[mid] < x) {
      min = mid + 1;
      } else if (a[mid] > x){
        max = mid - 1;
      }
    }
    if(a[mid]==x){
      printf(" x=%d ---> %d\n",x ,mid );

    }
    else {
      printf("見つかりませんでした。\n",x);
    }
  }
    return 0;
}//二分探索する関数

int main(void)
{
  char filename[20];
  int n,x,y;
  int a[DATA];
  int i;

  printf("ファイル名=");
  scanf("%s",filename);
  n=fileinput(filename,a);
   if(n==-1){
    printf("ファイルをオープンできません。\n");
  }
    else {
      printf("n = %d\n", n); // for debug
         for (i = 0; i <= n; i++) printf(" %d", a[i]);  // for debug
         puts(" : before sorting"); //for debug
      selectionsort(a,n);
      for (i = 0; i <= n; i++) printf(" %d", a[i]);  // for debug
      puts(" : after sorting");//for debug

      printf("探したい値を入力してください\n");
      y=a[binsearch(x,a,n)];

    }
   printf("またお会いしましょう\n");
   return (0);
}


かずま

Re: 関数を使ったコードについて

#21

投稿記事 by かずま » 1年前

しき さんが書きました:指摘されたところを直したらしっかり動くようになりました!
wc3.out

コード:

-3 -5 -1
このファイルで 0 を探すと「見つかりませんでした」
になるはずなのに、そうなりません。

max = n; を max = n - 1; に直していないからです。

しき
記事: 34
登録日時: 1年前

Re: 関数を使ったコードについて

#22

投稿記事 by しき » 1年前

最後まで至らなくて申し訳ないです・・。
今度こそこれで大丈夫だと思います!

コード:

#include <stdio.h>
#include <stdlib.h>
#define DATA 10000
 
char fileinput(char filename[20], int a[DATA])
{
 
  int n;
  FILE *fin;
 
  if ((fin=fopen(filename,"r"))==NULL){
  return(-1);
  }
  n=0;
  while(fscanf(fin, "%d", &a[n]) !=EOF) n++;
  fclose(fin);
  return n;
}//ファイルからデータを入力する関数
 
void selectionsort(int a[DATA],int n )
{
  int i,j,k;
  int tmp;
  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;
  }
}//データを整列する関数
 
int binsearch(int x, int a[DATA],int n)
{
  int min;
  int max;
  int mid;
 
  while (scanf("%d", &x)==1) {
   min=0;
    max=n-1;
    while(min <= max ) {
      mid = (min + max) / 2;
      if (a[mid]==x) {
        break;
      } else if (a[mid] < x) {
      min = mid + 1;
      } else if (a[mid] > x){
        max = mid - 1;
      }
    }
    if(a[mid]==x){
      printf(" x=%d ---> %d\n",x ,mid );
 
    }
    else {
      printf("見つかりませんでした。\n",x);
    }
  }
    return 0;
}//二分探索する関数
 
int main(void)
{
  char filename[20];
  int n,x,y;
  int a[DATA];
  int i;
 
  printf("ファイル名=");
  scanf("%s",filename);
  n=fileinput(filename,a);
   if(n==-1){
    printf("ファイルをオープンできません。\n");
  }
    else {
      printf("n = %d\n", n); // for debug
         for (i = 0; i <= n; i++) printf(" %d", a[i]);  // for debug
         puts(" : before sorting"); //for debug
      selectionsort(a,n);
      for (i = 0; i <= n; i++) printf(" %d", a[i]);  // for debug
      puts(" : after sorting");//for debug
 
      printf("探したい値を入力してください\n");
      y=a[binsearch(x,a,n)];
 
    }
   printf("またお会いしましょう\n");
   return (0);
}

アバター
みけCAT
記事: 6046
登録日時: 8年前
住所: 千葉県
連絡を取る:

Re: 関数を使ったコードについて

#23

投稿記事 by みけCAT » 1年前

binsearch関数で引数xの値を全く使わずに上書きしてしまうのは、おかしいと思います。
このような使い方をするなら、引数ではなく普通のローカル変数でいいでしょう。
また、main関数でyに代入した値を全く使っていないのも、おかしいと思いませんか?
関数内で出力までやってしまうのなら、main関数で値を取得する必要は無いですよね。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

しき
記事: 34
登録日時: 1年前

Re: 関数を使ったコードについて

#24

投稿記事 by しき » 1年前

無駄が多くて申し訳ないです。
もしよろしければ、xを使ったやり方、もしくは引数ではなくローカル変数を使うやり方を教えていただけませんか?
また、確かにyは不必要でした。修正しておきます。

かずま

Re: 関数を使ったコードについて

#25

投稿記事 by かずま » 1年前

なぜ、fileinput の返却値が char型なんですか?
ファイルの中のデータの個数が DATA より多かったらどうなりますか?
binsearch は常に 0 を返すんですか?
binsearch の中で入出力を実行したら、再帰呼出しに変換できないのでは?

インデントをしっかりつけましょう。

コード:

#include <stdio.h>

#define DATA 10000
 
int fileinput(const char *filename, int a[])
{
    int n, x;
    FILE *fin = fopen(filename, "r");
    if (fin == NULL) return -1;
    for (n = 0; n <= DATA && fscanf(fin, "%d", &x) == 1; n++)
        if (n < DATA) a[n] = x;
    fclose(fin);
    return n;
}
 
void selectionsort(int a[], int n)
{
    int i, j, k, tmp;
    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;
    }
}
 
int binsearch(int x, int a[], int min, int max)
{
    while (min <= max ) {
        int mid = (min + max) / 2;
        if (a[mid] == x)
            return mid;
        if (a[mid] < x)
            min = mid + 1;
        else if (a[mid] > x)
            max = mid - 1;
    }
    return -1;
}

int main(void)
{
    char filename[200];
    int a[DATA];
    int n, x, i;
 
    printf("ファイル名: ");
    scanf("%s", filename);
    n = fileinput(filename, a);
    if (n == -1) {
        puts("ファイルをオープンできません");
        return 1;
    }
    if (n > DATA) {
        puts("データが多すぎます");
        return 2;
    }
    selectionsort(a, n);
    puts("探したい値を入力してください");
    while (scanf("%d", &x) == 1) {
        i = binsearch(x, a, 0, n - 1);
        if (i >= 0)
            printf(" x = %d ---> %d\n", x, i);
        else
            puts("見つかりませんでした");
    }
    puts("またお会いしましょう");
    return 0;
}

かずま

Re: 関数を使ったコードについて

#26

投稿記事 by かずま » 1年前

すみません。訂正です。

35行目の else if (a[mid] > x) は、
else だけでかまいません。

しき
記事: 34
登録日時: 1年前

Re: 関数を使ったコードについて

#27

投稿記事 by しき » 1年前

かずまさん最後までありがとうございました。
このトピックでする話ではないかもしれませんが再帰呼び出しの件は別トピックでMathさんが言っていたように下記のような書き方でいいんでしょうか?

コード:

 if (a[mid] < x)
            return binsearch (x,a,min,mid-1);
        else if (a[mid] > x)
            return binsearch(x,a,mid+1,max);


しき
記事: 34
登録日時: 1年前

Re: 関数を使ったコードについて

#28

投稿記事 by しき » 1年前

上記の書き方ではだめでした・・。
6しか見つからないのはなぜなんでしょうか・・。

コード:

探したい値を入力してください
1
見つかりませんでした
2
見つかりませんでした
3
見つかりませんでした
4
見つかりませんでした
5
見つかりませんでした
6
x = 6 --> 2
0
見つかりませんでした
43
見つかりませんでした
123
見つかりませんでした


かずま

Re: 関数を使ったコードについて

#29

投稿記事 by かずま » 1年前

しき さんが書きました:このトピックでする話ではないかもしれませんが再帰呼び出しの件は別トピックでMathさんが言っていたように下記のような書き方でいいんでしょうか?
わかっていて、なぜこのトピックで話をするんですか?
なぜ、binsearch の全体を書かないんですか?
それから、インデントの意味をご存知ですか?

しき
記事: 34
登録日時: 1年前

Re: 関数を使ったコードについて

#30

投稿記事 by しき » 1年前

ごもっともです・・。
コードは見やすくなるよう心がけます。

返信

“C言語何でも質問掲示板” へ戻る