next up previous contents
Next: この文書について ... Up: 無題 Previous: A.8 make コマンド用コマンド・リスト (Makefile)

付 録B 相関内積計算プログラム (np.c)

 

指定したファイルのパターンのデータについて, そのパターンの平均値や相関内積値を計算し, そのファイルの最後に相関内積値を追加するプログラムである。

すでに,相関内積値が書き込まれている場合は変更せず,また, 間違ったデータが書き込まれている場合は正しいデータに書き直す等, 数種類の機能がある。 どのような処理を行ったかについては,メッセージが出力されるようになっている。

#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;
  }
}


Deguchi Toshinori
1998年03月12日 (木) 16時16分01秒 JST