C言語で遺伝的アルゴリズムを使った乱数のグループ分け

このQ&Aのポイント
  • C言語で遺伝的アルゴリズムを使って乱数のグループ分けを行うプログラムについての質問です。
  • プログラムを実行するとsegmentation faultが発生することがあり、その原因が分からないため回答を求めています。
  • 目的は与えられた乱数を2つのグループに分け、2つのグループの差をなるべく小さくすることです。
回答を見る
  • ベストアンサー

C言語 遺伝的アルゴリズムでのエラーについて

再度質問させていただきます。 以下のプログラムを実行するとsegmentation faultが出たり出なかったりします。 いまいち原因が分からないので回答お願いします。 ちなみに目的としては、 0~1の乱数が複数個与えられたときに、与えられた乱数を2つのグループに分け、その2グループの差ができるだけ小さくなるようにする。 といったものです。 よろしくお願いします。 #include<stdio.h> #include<stdlib.h> #include<time.h> //染色体の数 #define Number_of_ch 10 //エリート選抜の割合 #define Selection 0.3 //交叉率 #define Cross_ratio 0.7 //突然変異率 #define Mutation_ratio 0.2 //ループ回数 #define Number_of_loop 100 int main(int argc , char *argv[]) { int f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,x,y,z; long int Number_of_gene = argc-1;//遺伝子の数 int chromosome[Number_of_ch][Number_of_gene],distmin[Number_of_gene];//染色体と遺伝子 int best_chromosome[Number_of_gene],Number_of_cross=0,ch_1=0,ch_2=0,point=0,temp=0,temp_1=0,temp_2=0,abc=0,loop=0; double real_Number[Number_of_gene] , dist[Number_of_ch]; double best = 100.0; double sum0 = 0.0 , sum1 = 0.0 ; //入力値の記録 for(i=0 ; i<Number_of_gene ; i++){ real_Number[i] = atof(argv[i+1]); } srand((unsigned)time(NULL)); //染色体の初期化 for(j=0 ; j<Number_of_ch ; j++){ for(k=0 ; k<Number_of_gene ; k++){ chromosome[j][k] = rand() % 2;//0 or 1のグループ分け } } //----------------------ループ開始------------------------ while(loop < Number_of_loop){ //差分 for(l=0 ; l<Number_of_ch ; l++){ for(m=0 ; m<Number_of_gene ; m++){ if(chromosome[l][m] == 0){ sum0 = sum0 + real_Number[m]; } else{ sum1 = sum1 + real_Number[m]; } } if(sum0 > sum1){ dist[l] = sum0 - sum1; } else{ dist[l] = sum1 - sum0; } } //評価と記憶 for(n=0 ; n<Number_of_ch ; n++){ if(dist[n] < best){ best = dist[n]; for(o=0 ; o<Number_of_gene ; o++){ best_chromosome[o] = chromosome[n][o]; } } } //ソート for(p=0 ; p<Number_of_ch ; p++){ for(q=1 ; q<Number_of_ch-p+1 ; q++){ if(dist[q-1] > dist[q]){ for(r=0 ; r<Number_of_gene ; r++){ distmin[r] = chromosome[q][r]; chromosome[q][r] = chromosome[q-1][r]; chromosome[q-1][r] = distmin[r]; } } } } //エリートの選抜 for(s=Number_of_ch*Selection ; s<Number_of_ch ; s++){ for(t=0 ; t<Number_of_gene ; t++){ chromosome[s][t] = best_chromosome[t]; } } //交叉 Number_of_cross = Number_of_ch * Cross_ratio; for(u=0 ; u<Number_of_cross ; u++){ ch_1 = (Number_of_ch-1) * (rand()/32767); ch_2 = (Number_of_ch-1) * (rand()/32767); point = (Number_of_gene-1) * (rand()/32767); for(x=point ; x<Number_of_gene ; x++){ temp_1 = chromosome[ch_1][x]; for(y=0 ; y<Number_of_gene ; y++){ if(chromosome[ch_1][x] == chromosome[ch_2][y]){ temp_2 = chromosome[ch_2][x]; chromosome[ch_2][x] = chromosome[ch_2][y]; chromosome[ch_2][y] = temp_2; } for(z=0 ; z<Number_of_gene ; z++){ if(chromosome[ch_2][x] == chromosome[ch_1][z]){ chromosome[ch_1][x] = chromosome[ch_1][z]; chromosome[ch_1][z] = temp_1; } } } } } //突然変異 for(f=0 ; f<Number_of_cross ; f++){ for(g=0 ; g<Number_of_gene ; g++){ if(rand()/32767 < Mutation_ratio){ abc = (Number_of_gene-1) * (rand()/32767); temp = chromosome[f][g]; chromosome[f][g] = chromosome[f][abc]; chromosome[f][abc] = temp; } } } loop = loop + 1; } //結果の出力 printf("# best = %f \n",best); for(h=0 ; h<Number_of_gene ; h++){ printf("%d",best_chromosome[h]); } printf("\n"); }

質問者が選んだベストアンサー

  • ベストアンサー
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.3

Segmantation Fault は領域外へアクセスしたときに発生するもので、プログラム上の原因は次のようなものがほとんどです ・確保させていない領域にアクセスした  NULL、freeした後の領域等 ・配列の添字が範囲外 ですから、まずは、上記の点問題無いかを調べます。 エラーなくコンパイルできたかどうかは関係ありません。 で、プログラムを全部チェックするのは面倒ですが、それでも、斜め読みでもわかるくらいおかしな点を http://okwave.jp/qa/q8589069.html で指摘させていただきましたが、今回のプログラムでもまったく直ってません。 (rand()/32767); おそらく、[0,1]の乱数を期待しているようですが、2つの理由から、そうはなっていません。 そのことは理解できていますか?

y_ssoccerking
質問者

お礼

RAND_MAXは理解し、訂正したのですが訂正前のものをのせてしまいました。 無事解決できました。 ありがとうございます。

その他の回答 (2)

  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.2

なんというか…いまいち読む気にならないですねぇ……。 # define定義と変数が入り交じる感じで読みにくい。 とりあえず…… >if(rand()/32767 < Mutation_ratio){ >abc = (Number_of_gene-1) * (rand()/32767); の結果は正常なんですかね? # abcが0から(Number_of_gene-1)の範囲に間違いなく収まります? ご使用の環境ではRAND_MAXはいくつなんでしょう? # 32767というマジックナンバーは…なんでしょう?? ちなみに…私なら除算ではなく剰余を使いますけどね。 abc = rand() % Number_of_gene; とか。(これならNumber_of_gene以上の値にはならないのでバッファオーバーランしないし)

  • kngj1740
  • ベストアンサー率18% (197/1052)
回答No.1

直接の回答にはなりません。開発環境のデバック機能を利用して、落ちるところ(直前?)を突き止め、ロードマップなどを参照してどのステートメントかを突き止める。あるいはソースレベルデバッグが可能な開発環境ならさらに楽です。そこの変数を確認、多分、配列の大きさを超えてアクセスしようとしてるのでは。乱数発生で行われているため、毎回同じ結果にならないだけと思います。

関連するQ&A

  • C言語 遺伝的アルゴリズムでのエラーについて

    与えられた乱数を二つのグループにわけ、その差が小さくなるようなプログラムを書いているつもりです。 が、コンパイルし、実行したところsegmentation fault が表示されます。 segmentation fault が表示される理由はわかっていますが、どこでそういった現象がおこっているのか判断できない状況です。 どなたかよろしくお願いします。 #include<stdio.h> #include<stdlib.h> #include<time.h> //染色体の数 #define Number_of_ch 10 //エリート選抜の割合 #define Selection 0.3 //交叉率 #define Cross_ratio 0.7 //突然変異率 #define Mutation_ratio 0.1 //ループ回数 #define Number_of_loop 100 int main(int argc , char *argv[]) { int f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,x,y,z; int Number_of_gene = argc-1;//遺伝子の数 int chromosome[Number_of_ch][Number_of_gene],distmin[Number_of_gene];//染色体と遺伝子 int best_chromosome[Number_of_gene],Number_of_cross=0,ch_1=0,ch_2=0,point=0,temp=0,temp_1=0,temp_2=0,abc=0,loop=0; float real_Number[Number_of_gene] , dist[Number_of_ch] , best = 100.0; float sum0 = 0.0 , sum1 = 0.0 ; //入力値の記録 for(i=0 ; i<argc ; i++){ real_Number[i] = atof(argv[i+1]); } srand((unsigned)time(NULL)); //染色体の初期化 for(j=0 ; j<Number_of_ch ; j++){ for(k=0 ; k<Number_of_gene ; k++){ chromosome[j][k] = rand() % 2;//0 or 1のグループ分け } } //----------------------ループ開始------------------------ while(loop < Number_of_loop){ //差分 for(l=0 ; l<Number_of_ch ; l++){ for(m=0 ; m<Number_of_gene ; m++){ if(chromosome[l][m] == 0){ sum0 = sum0 + real_Number[k]; } else{ sum1 = sum1 + real_Number[k]; } } dist[l] = abs(sum1 - sum0); } //評価と記憶 for(n=0 ; n<Number_of_ch ; n++){ if(dist[n] < best){ best = dist[n]; for(o=0 ; o<Number_of_gene ; o++){ best_chromosome[o] = chromosome[n][o]; } } } //ソート for(p=0 ; p<Number_of_ch ; p++){ for(q=1 ; q<Number_of_ch-p+1 ; q++){ if(dist[q-1] > dist[q]){ for(r=0 ; r<Number_of_gene ; r++){ distmin[r] = chromosome[q][r]; chromosome[q][r] = chromosome[q-1][r]; chromosome[q-1][r] = distmin[r]; } } } } //エリートの選抜 for(s=Number_of_ch*Selection ; s<Number_of_ch ; s++){ for(t=0 ; t<Number_of_gene ; t++){ chromosome[s][t] = best_chromosome[t]; } } //交叉 Number_of_cross = Number_of_ch * Cross_ratio; for(u=0 ; u<Number_of_cross ; u++){ ch_1 = (Number_of_ch-1) * (rand()/32767); ch_2 = (Number_of_ch-1) * (rand()/32767); point = (Number_of_gene-1) * (rand()/32767); for(x=point ; x<Number_of_gene ; x++){ temp_1 = chromosome[ch_1][x]; for(y=0 ; y<Number_of_gene ; y++){ if(chromosome[ch_1][x] == chromosome[ch_2][y]){ temp_2 = chromosome[ch_2][x]; chromosome[ch_2][x] = chromosome[ch_2][y]; chromosome[ch_2][y] = temp_2; } for(z=0 ; z<Number_of_gene ; z++){ if(chromosome[ch_2][x] == chromosome[ch_1][z]){ chromosome[ch_1][x] = chromosome[ch_1][z]; chromosome[ch_1][z] = temp_1; } } } } } //突然変異 for(f=0 ; f<Number_of_cross ; f++){ for(g=0 ; g<Number_of_gene ; g++){ if(rand()/32767 < Mutation_ratio){ abc = (Number_of_gene-1) * (rand()/32767); temp = chromosome[f][g]; chromosome[f][g] = chromosome[f][abc]; chromosome[f][abc] = temp; } } } loop = loop + 1; } //結果の出力 printf("# best = %f \n",best); for(h=0 ; h<Number_of_gene ; h++){ printf("%d",best_chromosome[h]); } printf("\n"); }

  • 遺伝的アルゴリズム

    遺伝的アルゴリズムのプログラムを作っているのですがサンプルソースの下の関数のやってこるこがよく意味がわかりません。よかったら解説 お願いします。 // 一点交叉 void one_point_crossover(struct genotype *ind) { int i, ia, ib; // 個体インデックス int j; // 遺伝子座インデックス int c; // 交叉点 int test[M]; // 個体の利用フラグ int temp[N]; // 遺伝子を入れ替えるための仮変数 // 4/24修正 int r; // 乱数値 for(i=0; i<M; i++) test[i] = 0; ia = ib = 0; for(i=0; i<M/2; i++) { // 個体をランダムにペアリング for(; test[ia]==1; ia=(ia+1)%M); test[ia] = 1; r = random() % (M-2*i) + 1; while(r>0) { ib=(ib+1)%M; for(; test[ib]==1; ib=(ib+1)%M); r--; } test[ib] = 1; // 個体iaとibを交叉 if(flip(Pc)) { c = random() % N; for(j=0; j<c; j++) { temp[j] = ind[ia].gene[j]; ind[ia].gene[j] = ind[ib].gene[j]; ind[ib].gene[j] = temp[j]; } } } } // End of one_point_crossover()

  • C言語について質問です。

    ソートについて勉強していて、乱数列の要素数Nの値を変えていきバブルソートの交換回数、比較回数を数えるプログラムを作り、後は処理時間について調べたいのですが、処理時間を出力させることはできたんですが、単位がわかりません。教えてください。 以下に乱数を生成するrand.cとバブルソートを行うbubblesort.cを記載します。 rand.c #include <stdio.h> #include <stdlib.h> #include <time.h> #define N 1000 int num[N]; int makeDataFile ( void ) { int i; FILE *fp; char s[100]; int num[N]; srand ( ( unsigned )time ( NULL ) ); fp = fopen ("rand1.txt", "w" ); if ( fp == NULL ) exit(1); for ( i = 0; i < N; i++ ){ fprintf ( fp, "%d\n", rand()%100 ); } fclose ( fp ); fp = fopen ( "rand1.txt", "r" ); if ( fp == NULL ) exit(1); while( fgets ( s, sizeof (s), fp ) ) { printf ( s ); } fclose ( fp ); return N; } bubblesort.c #include <stdio.h> #include <time.h> extern int makeDataFile ( void ); extern int num[]; void BubbleSort ( int x[] , int n ); void Show ( int x[] , int n ); int comp; int swap; void BubbleSort ( int x[] , int n ) { int i, j, tmp; for ( i = 0; i < n-1; i++ ) { for ( j = n-1; j > i; j-- ){ comp++; if ( x[i] > x[j] ){ swap++; tmp = x[j]; x[j] = x[i]; x[i]= tmp; Show ( x , n ); } } } } void Show ( int x[] , int n ) { while ( n-- ) printf ( "%d " , *x++ ); printf ( "\n" ); } int main(void) { int i, j, n , tmp; FILE *fp; comp = 0; swap = 0; n = makeDataFile(); fp = fopen ( "rand1.txt", "r" ); if ( fp == NULL ) return 1; for ( i = 0; i < n; i++ ){ fscanf ( fp, "%d", &(num[i] ) ); } fclose ( fp ); printf ( "\nbefore bubblesort\n" ); Show ( num , n ); printf ( "\n" ); printf ( "progress bubblesort\n" ); BubbleSort ( num , n ); printf ( "\n" ); printf ( "after bubblesort\n" ); Show ( num , n ); printf ( "\n" ); printf ( "count of comparisons : %d\n" , comp ); printf ( "count of swap : %d\n" , swap ); return 0; } 実行結果: (ソートは省略) count of comparisons : 499500 count of swap : 14848 2.950000 と出力されたのですが読み方?単位が分かりません。教えてください。2分ぐらいかかった気がします。

  • C言語について質問です。

    ソートについて勉強していて、乱数列の要素数Nの値を変えていきバブルソートの交換回数、比較回数を数えるプログラムを作り、後は処理時間について調べたいのですが、処理時間を出力するのはどうやってやるのですか?教えてください。以下に乱数を生成するrand.cとバブルソートを行うbubblesort.cを記載します。これに処理時間を出力するようにしてもらいたいのですが、どうしたらいいですか?解説とソースファイルをよろしくお願いします。 rand.c #include <stdio.h> #include <stdlib.h> #include <time.h> #define N 1000 int num[N]; int makeDataFile ( void ) { int i; FILE *fp; char s[100]; int num[N]; srand ( ( unsigned )time ( NULL ) ); fp = fopen ("rand1.txt", "w" ); if ( fp == NULL ) exit(1); for ( i = 0; i < N; i++ ){ fprintf ( fp, "%d\n", rand()%100 ); } fclose ( fp ); fp = fopen ( "rand1.txt", "r" ); if ( fp == NULL ) exit(1); while( fgets ( s, sizeof (s), fp ) ) { printf ( s ); } fclose ( fp ); return N; } bubblesort.c #include <stdio.h> #include <time.h> extern int makeDataFile ( void ); extern int num[]; void BubbleSort ( int x[] , int n ); void Show ( int x[] , int n ); int comp; int swap; void BubbleSort ( int x[] , int n ) { int i, j, tmp; for ( i = 0; i < n-1; i++ ) { for ( j = n-1; j > i; j-- ){ comp++; if ( x[i] > x[j] ){ swap++; tmp = x[j]; x[j] = x[i]; x[i]= tmp; Show ( x , n ); } } } } void Show ( int x[] , int n ) { while ( n-- ) printf ( "%d " , *x++ ); printf ( "\n" ); } int main(void) { int i, j, n , tmp; FILE *fp; comp = 0; swap = 0; n = makeDataFile(); fp = fopen ( "rand1.txt", "r" ); if ( fp == NULL ) return 1; for ( i = 0; i < n; i++ ){ fscanf ( fp, "%d", &(num[i] ) ); } fclose ( fp ); printf ( "\nbefore bubblesort\n" ); Show ( num , n ); printf ( "\n" ); printf ( "progress bubblesort\n" ); BubbleSort ( num , n ); printf ( "\n" ); printf ( "after bubblesort\n" ); Show ( num , n ); printf ( "\n" ); printf ( "count of comparisons : %d\n" , comp ); printf ( "count of swap : %d\n" , swap ); return 0; }

  • C言語について質問です。

    前に質問した訂正です。前の質問に関しては質問の意図が伝わりにくい文章で本当に申し訳ないと思っています。 乱数列の要素数Nの値を変えていきバブルソートの交換回数、比較回数を数えるプログラムを作り、後は処理時間について調べたいのですが、処理時間を出力させることはできたんですが、単位がわかりません。教えてください。 以下に乱数を生成するrand.cとバブルソートを行うbubblesort.cを記載します。 rand.c #include <stdio.h> #include <stdlib.h> #include <time.h> #define N 1000 int num[N]; int makeDataFile ( void ) { int i; FILE *fp; char s[100]; int num[N]; srand ( ( unsigned )time ( NULL ) ); fp = fopen ("rand1.txt", "w" ); if ( fp == NULL ) exit(1); for ( i = 0; i < N; i++ ){ fprintf ( fp, "%d\n", rand()%100 ); } fclose ( fp ); fp = fopen ( "rand1.txt", "r" ); if ( fp == NULL ) exit(1); while( fgets ( s, sizeof (s), fp ) ) { printf ( s ); } fclose ( fp ); return N; } bubblesort.c #include <stdio.h> #include <time.h> extern int makeDataFile ( void ); extern int num[]; void BubbleSort ( int x[] , int n ); void Show ( int x[] , int n ); int comp; int swap; void BubbleSort ( int x[] , int n ) { int i, j, tmp; for ( i = 0; i < n-1; i++ ) { for ( j = n-1; j > i; j-- ){ comp++; if ( x[i] > x[j] ){ swap++; tmp = x[j]; x[j] = x[i]; x[i]= tmp; Show ( x , n ); } } } } void Show ( int x[] , int n ) { while ( n-- ) printf ( "%d " , *x++ ); printf ( "\n" ); } int main(void) { int i, j, n , tmp; FILE *fp; comp = 0; swap = 0; n = makeDataFile(); clock_t start , finish; double duration; start = clock(); fp = fopen ( "rand1.txt", "r" ); if ( fp == NULL ) return 1; for ( i = 0; i < n; i++ ){ fscanf ( fp, "%d", &(num[i] ) ); } fclose ( fp ); printf ( "\nbefore bubblesort\n" ); Show ( num , n ); printf ( "\n" ); printf ( "progress bubblesort\n" ); BubbleSort ( num , n ); printf ( "\n" ); printf ( "after bubblesort\n" ); Show ( num , n ); printf ( "\n" ); finish = clock(); duration = (double)(finish-start) / CLOCKS_PER_SEC; printf ( "count of comparisons : %d\n" , comp ); printf ( "count of swap : %d\n" , swap ); printf ( "%lf\n" , duration ); return 0; } 実行結果: >gcc rand.c bubblesort.c (ソートは省略) count of comparisons : 499500 count of swap : 14848 2.950000 と出力されたのですが読み方?単位が分かりません。教えてください。自分の答えとしては2分55秒だと思うんですが合ってますか?連続質問ですいません。

  • C言語についてです。

    EXELEファイルから値を読みこんで、各自のBMIと全体の身長・体重の平均値を求めるプログラムを作成したいんですが…C言語で…。途中までで混乱してしまい、あっているかも分からないのでお願いしたいです。よろしくお願いします。ヒントだけでもありがたいです。 下がそのファイルです。 height weight 170.7 52.9 166.8 71.3 171.4 58.5 173.4 76.7 176.1 80.2 184 89.1 179 64.7 177.2 78.5 177.7 80.7 173.8 64 167.7 60.3 181.6 72.3 162.4 53 177.4 69.6 178 76.4 174 77.2 185.4 86 172 68.5 172.7 60 166.5 62 171.3 69.6 177 79 174.8 82.6 167.5 69.2 176.8 80.1 181.5 76 177.3 76.4 169.4 51.8 165.2 73.2 175.3 72.3 181.5 72.4 171.5 68.8 176 73.2 186 99.8 167.3 65.5 176.1 78 183.3 77.2 177.5 59.5 180.3 62 171.2 74.7 175 87.2 176 80 171.8 50.6 平均身長の値を出すプログラムは出ているので…これもあわせてBMIと平均体重出してくれるとうれしいです。 /* basic claculation */ #include <stdio.h> #include <math.h> int main(void) { int i, ii; int ntotal; double sum_height; double weight[50], height[50]; double mean_height; char w[6],h[6]; FILE *fp; /* initial setting */ /* ntotal: total word number */ /* sum : total character number */ ntotal = 0; sum_height = 0; /* file open */ /* my data file is weight-height.data */ /* which is in my root directory */ fp = fopen("./weight-height.data","r"); /* skip character reading. */ fscanf(fp,"%s,%s",w,h); /* ntotal: total number */ /* sum : total value */ for (i=0;i<=47;i++) { if (feof(fp)) break; fscanf(fp,"%lf,%lf",&weight[i],&height[i]); printf(" weight = %lf height = %lf \n",weight[i],height[i]); sum_height = sum_height + height[i]; } fclose(fp); ntotal = i; printf(" 全人数 = %d \n",ntotal); mean_height = sum_height /ntotal; printf(", 平均身長 = %lf \n",mean_height); return(0); }

  • C言語/ランダムbeepのプログラム方法

    プログラムを書いていますが理解に苦しんでいます。 勉強し始めたばかりなのでかなりハードです。どなたか助けていただけませんか。 前に進めずにいます。 何をしたいかというと、マッチングゲームの中の一部でランダムなビープサウンドにあわせて反応して答えを返すというものです。答えられなければ点数がマイナスになります。 まず、数字をランダムに1から10の間で生成し、出た数字がある特定の数字だとビープサウンドが流れるという仕組みを考えたのですがどうでしょうか。 本当に切羽詰っています。助けてください。 // rand.cpp : Defines the entry point for the console application. // #include <stdafx.h> #include <stdlib.h> /*This header is for rand srand code)*/ int main (void) { unsigned int seed; int i,run=0; printf("Choose a level of difficulty"); scanf("%d", &seed); /*&seed is for "unsigned" int*/ printf("\n"); srand(seed); /*generate a number 0-10*/ i=1+(int) (10.0*rand()/(RAND_MAX+1.0)); /*if a number is 1, beep sound comes out*/ if(i==1) for(int j=0; j<i; j++) printf("\a"); return 0; }

  • 円周率 πの値

    円周率πの値を求めたのですがNを大きくすると3.1415・・・に近づくはずですが、うまくいきません。どうすればいいのか検討がつきませんので、ご指摘お願いします。 float myrand() { float ans; ans=(float)rand()/(RAND_MAX); return(ans); } main() { int i,sum; long N; float ans,x,y,r,p; srand((unsigned)time(NULL)); sum=0; for(N=10;N<=1000000;N*=10){ for(i=10;i<N;i++){ x=myrand(); y=myrand(); r=x*x+y*y; if(r<=1){ sum++; } } ans=(float)(sum)/N; p=ans*4; printf("%d %f\n",N,p); } getch(); exit(0); } 実行結果 10 0.000000 100 2.640000 1000 3.440000 10000 3.483600 100000 3.490640 1000000 3.491268

  • C言語の添削

    「C言語基礎課題1」 #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <tchar.h> #include <ctype.h>                                       #include <string.h> #define MAX 100 /*点数*/ int flag; double avg(double t[],int n); int str_check(char s[]);                                        int main() { int number; //人数 double score[MAX]; //点数 char temp[MAX]; char str[MAX]; //名前 double ans; //平均成績 int i=0; //カウンタ変数 //人数の決める printf("人数を入力して下さい。\n"); scanf("%d",&number); //名前の入力 for(i=0;i<number;i++) { printf("%d番様の名前を入力して下さい。\n",i+1); scanf("%s",&str[i]); } //点数の入力 for(i=0;i<number;i++) { printf("%d番様の点数を入力して下さい。\n",i+1); scanf("%s",&temp); str_check(temp); if(flag==1) { score[i]=atoi(temp); //点数入力で有効範囲をチェック if(score[i]<0 || score[i]>100) { printf("0-100点の範囲を入力して下さい。\n"); i--; } } if(flag==0) { printf("点数を数字で入力して下さい。\n"); i--; } } ans =avg(score,number); printf("\n=====入力内容一覧と成績平均値======\n"); for(i=0;i<number;i++) { printf("%d番の点数は%3.2lfです。\n",i+1,score[i]); } printf("平均点は%3.2lfです。\n",ans); printf("=====================================\n"); getch(); return 0; } /*avg関数の定義*/ double avg(double t[],int n) { int i; double sum; sum = 0.0; for(i=0;i<n;i++) { sum += t[i]; } return sum/n; } /*点数入力で文字か数字かチェック*/ int str_check(char s[]) { int i=0,n; //カウンタ変数 n=strlen(s); while(s!='\0') { if(s[i]>='0'&&s[i]<='9'||s[i]=='.') { i++; } else { break; } } if(i==n) { flag=1; } else { flag=0; } return flag; } [最初に組んだソースプログラム] #include<stdio.h> #include<stdio.h> #define NUM 3 /*点数*/ #define Name 3 /*人数*/ #include<conio.h> double avg(int t[]); struct stList{ char str[Name][100]; int score[NUM]; int i,j; }; int main(void) { int score[NUM]; //char str[Name]; char str[100]; int i,j; double ans; printf("名前を入力して下さい。\n",Name); for(i=0;i<Name;i++){ scanf("%s",&str[Name]); } // if(score[NUM]=0 || score[NUM]<=100) //{ // printf("点数を入力して下さい。\n",NUM); //} printf("点数を入力して下さい。\n",NUM); for(i=0;i<NUM;i++) { scanf("%d",&score[i]); if(score[i]<0 || score[i]>100) { printf("0-100点の範囲を入力して下さい。\n"); i--; } } for(j=0;j<NUM;j++){ printf("%d番目の人の点数は%dです。\n",j+1,score[j]); } ans =avg(score); printf("平均点は%3.2lfです。\n",ans); getch(); return 0; } /* avg関数の定義 */ double avg(int t[]) { int i; double sum; sum = 0.0; for(i=0;i<3;i++){ sum += t[i]; } return sum/Name; } 「一人分のデータを保持する構造体(文字列と整数の変数をメンバに持つ)を用意し、3人分の名前と成績 (最大値100、最小値0)を入力でき、入力が終了したら、入力内容一覧と成績の平均値を表示する プログラムを作成せよ。 ※考えうる限りの異常系処理の導入、関数化を行うこと。」 研修で以下の指摘を受けました。 (1)compare関数が使われていない。 (2)名前入れる変数が3つ不明 (3)カウンタ変数がi,j,s,tになっている理由は? (4)名前を入力しなかった時の処理 (5)点数を処理しなかった時の処理 (6)定数NUMで人数3を指定できるようにしているのにプログラムはそれを利用仕切れていない(名前入力が固定3人)ので無意味 (7)if(tmp=0 || tmp<=100)←これなんでしょうか? (8)平均点表示の少数点以下有効桁数はどうなっているのか? (9)点数入力で文字を入れたときの処理 (10)点数入力で有効範囲外の数字を入れた時の処理 ちなみに最大値、最小値はdefineして欲しいです。理由は(2)に読めば分かる (11)変数名が謎なのが多い 課題のキーワードのどこにも出て来ないですし言葉だから 後、添付ファイルを添付します。 最初のソースプログラム名「最初に組んだもの」修正したものが「C言語基礎課題1」と名付けています。 いづれのソースプログラムも構造体を用意出来てないように思うのですがいかかですか?

  • C言語 初心者です。

    今、英単語帳を作っているのですが、以下のソースではできません。 作ろうとしているプログラムは、a bを登録した場合、次がaabと来たら、 a aab bといったようにしたいのですが、できません。教えてください。 #include <stdio.h> #include <string.h> #define NUMBER 50 /*--- 単語帳の構造体*/ typedef struct { char *word; } words; /*--- 文字列strから文字列wordを検索する ---*/ char *str_chr(const char *str, int w) { for ( ; *str; *str++){ if (*str == w){ return ((char *)str); } } return (NULL); /*検索したが該当しないときはNULLを返す*/ } /*--- 単純交換ソート ---*/ void swap(int *x, int *y) { int temp = *x; *x = *y; *y = temp; } /*--- 配列dataの先頭n個の要素を昇順にソート ---*/ void sort(words data[], int n) { int k = n - 1; while (k >= 0){ int i, j; for (i = 1, j = -1; i <= k; i++) if (data[i - 1].word > data[i].word){ j = i - 1; swap(&data[i], &data[j]); } k = j; } } int main(void) { words word[NUMBER][20] = {{0},{0}}; char str[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; char w[128], *p; int count = 0; do{ printf("単語を入力してください。:"); /*単語を入力する*/ scanf("%s", w); p = str_chr(str, w); }while(p == NULL); count++; if(count >= NUMBER){ /*登録件数を調べる*/ printf("件数いっぱいです。\n"); } return (0); sort(word, NUMBER); return (0); }

専門家に質問してみよう