指定したファイルのパターンのデータについて, そのパターンの平均値や相関内積値を計算し, そのファイルの最後に相関内積値を追加するプログラムである。
すでに,相関内積値が書き込まれている場合は変更せず,また, 間違ったデータが書き込まれている場合は正しいデータに書き直す等, 数種類の機能がある。 どのような処理を行ったかについては,メッセージが出力されるようになっている。
#include <stdio.h> #define PN 4 /* パターン数 */ #define N 100 /* 要素数 */ #define NS 6 /* 内積値数 */ main(int argc,char *argv[]) { FILE *f;/* ファイルポインタ */ int P[PN][N];/* パターン配列 */ double heikin;/* パターン平均 */ int naiseki[NS];/* 相関内積 */ int i,j,k,l;/* その他の変数 */ int nai_kaki;/* 内積値有無判定 */ int nai_f[NS];/* ファイルに内積値が書き込まれていた場合のその値 */ char fname[50];/* ファイル名 */ /* ファイルが開けない場合に chmod を実行する関数 */ FILE *fchmod(int, char []); /* コマンドラインのパラメータの使用方法 */ if(argc != 2){ printf("np <内積調査ファイル記号>\n"); printf("\tファイル名: pat_<内積調査ファイル記号>.dat\n"); exit(-1); } /* 指定したファイルを開く */ sprintf(fname,"pat_%s.dat",argv[1]); if((f=fopen(fname,"r")) == NULL){ /* 指定したファイルがない場合 */ printf("ファイルがないか,開くことができません!!\007\n"); exit(-1); } /* 各パターンの平均値計算・画面表示 */ printf("平均:\n"); for(i=0; i<PN; i++){ heikin=0; printf("pattern-%d ",i); for(j=0; j<N; j++){ if(fscanf(f,"%d",&P[i][j])!=1){ /* データを正しく入力できなかった場合 */ printf("\n指定したファイルのフォーマットが違っています!!\007\n"); exit(-1); } if(P[i][j]!=0 && P[i][j]!=1){ /* データに 0,1 以外の数値が含まれている場合 */ printf("\nパターンデータに 0,1 以外の数値が含まれています!!\007\n"); exit(-1); } heikin += P[i][j]; } heikin /= N; printf("%lf\n",heikin); } /* 内積値がすでに書き込まれているかを判定 */ for(i=0; fscanf(f,"%d",&nai_f[i]) != EOF && i<NS+1; i++); if(i==NS) /* すでに書き込まれている場合 */ nai_kaki=-1; else if(i==0) /* 書き込まれていない場合 */ nai_kaki=0; else /* 書き込まれているが数が違っている場合(内積値を書きなおす場合) */ nai_kaki=1; fclose(f); /* NS 個の相関内積値の計算・画面表示 */ printf("相関内積:\n"); l=0; for(i=0; i<PN-1; i++) for(j=i+1; j<PN; j++){ naiseki[l]=0; for(k=0; k<N; k++) if(P[i][k] == P[j][k]) naiseki[l]++; else naiseki[l]--; printf("pattern-%d & pattern-%d %4d\n",i,j,naiseki[l]); /* すでに書き込まれている内積値が正しいかどうかの判定 */ if(nai_kaki==-1 && naiseki[l]!=nai_f[l]) /* 正しくない場合(内積値を書きなおす場合) */ nai_kaki=1; l++; } /* 内積値を書き足すのかどうかの判定 */ if(nai_kaki == 0){ /* 内積値をパターンデータの後に書き足す場合 */ if((f = fopen(fname,"a"))==NULL){ /* ファイルが開けない場合 */ fclose(f); f=fchmod(nai_kaki,fname); } printf("指定したファイルに内積値を追加します。\n"); fprintf(f,"\n"); } else /* 内積値を書きなおすか書きなおさないかを判定 */ if(nai_kaki == 1){ /* 内積値を書きなおす場合(簡単のためパターンデータ自体も書きなおす) */ if((f = fopen(fname,"w"))==NULL){ /* ファイルが開けない場合 */ fclose(f); f=fchmod(nai_kaki,fname); } printf("指定したファイルの内積値を書き換えます。\n"); for(i=0; i<PN; i++){ for(j=0; j<N; j++) /* パターンをわかりやすくするため,要素を 10 ごとに改行する */ if(j%10==9) fprintf(f,"%d\n",P[i][j]); else fprintf(f,"%d ",P[i][j]); fprintf(f,"\n"); } } else{ /* 書きなおさない場合(終了) */ printf("内積値がすでに書き込まれているので,そのまま終了します。\n"); exit(0); } /* 内積値書き込み */ for(i=0; i<NS-1; i++) fprintf(f,"%d ",naiseki[i]); fprintf(f,"%d\n",naiseki[i]); fclose(f); } /* ファイルが開けない場合に chmod を実行する関数 */ FILE *fchmod(int nk, char fn[]) { char ff[2];/* ファイルモード */ char yn[10];/* Yes, No 判定 */ char scf[60];/* chmod 実行コマンド */ FILE *f;/* ファイルポインタ */ /* 警告表示 */ if(nk==0) printf("指定したファイルに内積値を書き足すことができません!!\007\n"); else printf("指定したファイルの内積値を書き換えることができません!!\007\n"); /* chmod を実行するかどうかを選択する */ printf("'chmod u+w %s' を実行しますか?(Yes:y, No:n)\n:",fn); shitei: scanf("%s",yn); /* 入力された文字を判定 */ if((yn[0]=='y' || yn[0]=='Y') && yn[1]=='\0'){ /* chmod コマンドを実行する */ sprintf(scf,"chmod u+w %s",fn); system(scf); /* ファイルモードの判定 */ if(nk==0) sprintf(ff,"a"); else sprintf(ff,"w"); /* ファイルをもう一度開きなおす */ if((f=fopen(fn,ff))==NULL){ /* またファイルを開けなかった場合(警告を出して終了) */ printf("%s を実行しましたが失敗しました!!\007\n",scf); fclose(f); exit(-1); } else /* ファイルを開くことができた場合(ファイルポインタを返す) */ return f; } /* y, Y の文字以外が入力された場合の文字判定 */ if((yn[0]=='n' || yn[0]=='N') && yn[1]=='\0'){ /* n,N が入力された場合(警告を出して終了) */ printf("ファイルを書き換えずに終了します。\007\n"); exit(-1); } else{ /* その他の文字が入力された場合(警告を出して再入力を促す) */ printf("y と n 以外の文字が入力されました。\007\n"); printf("もう一度指定しなおして下さい。(Yes:y, No:n)\n:"); goto shitei; } }