指定したファイルのパターンのデータについて, そのパターンの平均値や相関内積値を計算し, そのファイルの最後に相関内積値を追加するプログラムである。
すでに,相関内積値が書き込まれている場合は変更せず,また, 間違ったデータが書き込まれている場合は正しいデータに書き直す等, 数種類の機能がある。 どのような処理を行ったかについては,メッセージが出力されるようになっている。
#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;
}
}