Yamamoto's Laboratory
講義ノート1E 情報処理I → 配列とファイル操作の練習(プログラム解説)

配列とファイル操作の練習(プログラム解説)

先週、渡したプリントに書かれていた練習問題の解答を示します。

目次

  1. ファイル出力
  2. ファイル入力
  3. 温度のデータ処理
  4. 数値ファイルの清書
  5. アクセスカウンター
  6. 総合応用問題

ファイル出力

#include <stdio.h>

int main(void)
{
  FILE *fp_write;
  int i;
  
  /*-------- エラー処理付きファイルオープン ---------------*/

  if((fp_write = fopen("ex1_out.txt","w"))==NULL){
    printf("ファイルが開けません\n");
    return 1;
  }


  /*-------- 整数(1 - 10000)の書き出し ------------------*/

  for(i=1; i<=10000; i++){
    fprintf(fp_write,"%d\n", i);
  }

  /*-------- ファイルのクローズ -------------------------*/
  
  fclose(fp_write);
  
  return 0;
}

ファイル入力

#include <stdio.h>

int main(void){
  FILE *fp;
  double data[10000], sum;
  int i;
 
  /* --------------- ファイルのオープン ------------------------*/
 
  if((fp=fopen("/tmp/1e/exercise2.txt","r"))==NULL){
    printf("can not open the file\n");
    return 1;
  }


  /* --------------- ファイルのデータを配列に代入 ---------------*/
  
  for(i=0; i<=9999; i++){
    fscanf(fp, "%lf", &data[i]);
  }
  

  /* --------------- ファイルのクローズ ------------------------*/

  fclose(fp);


  /* --------------- 合計の計算 ------------------------*/

  sum=0.0;
  for(i=0; i<=9999; i++){
    sum += data[i];
  }
  
  
  /* --------------- 合計の表示 ------------------------*/

  printf("sum = %lf\n",sum);
  
  return 0;	
  
}

温度のデータ処理

#include <stdio.h>

int main(void){
  FILE *fp;
  double temp[31][24];
  double max_day[31], min_day[31], av_day[31];
  double max_nov, min_nov, av_nov;
  double sum_day, sum_nov;
  int dates, hours;
  int i, j;

  /* --------------- 日数と時間の設定 --------------------------*/

  dates = 30;
  hours = 24;

  /* --------------- ファイルのオープン ------------------------*/

  if((fp=fopen("/tmp/1e/temperature.txt","r"))==NULL){
    printf("can not open the file\n");
    return 1;
  }


  /* --------------- ファイルからデータを読み込む ---------------*/
  
  for(i=1; i<=dates; i++){
    for(j=0; j<=hours-1; j++){
      fscanf(fp, "%lf", &temp[i][j]);
    }	
  }
  
  
  /* --------------- 最大と最小、平均の計算 --------------------*/

  max_nov = -9999;                  /* 11月の仮の最高気温 */
  min_nov = 9999;                   /* 11月の仮の最低気温 */
  sum_nov = 0.0;                    /* 11月の気温の合計の初期値 */
  
  for(i=1; i<=dates; i++){          /* iは、日にちを表す */
    
    max_day[i] = -9999;             /* i日の仮の最高気温 */
    min_day[i] = 9999;              /* i日の仮の最低気温 */
    sum_day = 0.0;                  /* i日の気温の合計の初期値 */

    for(j=0; j<=hours-1; j++){      /* iは時刻を表す    */       
      sum_day += temp[i][j];        /* 時刻毎の気温の合計 */

      if(temp[i][j] > max_day[i]){  /* i日の最大気温の探索 */
	max_day[i] = temp[i][j];
      }
      
      if(temp[i][j] < min_day[i]){  /* i日の最低気温の探索 */
	min_day[i] = temp[i][j];
      }      
    }
    
    av_day[i]=sum_day/hours;        /* i日の平均気温の計算 */
    
    sum_nov += av_day[i];           /* 11月1日までの平均気温の和 */
    
    if(max_day[i] > max_nov){       /* 11月の最大気温の探索 */
      max_nov = max_day[i];
    }
    
    if(min_day[i] < min_nov){       /* 11月の最低気温の探索 */
      min_nov = min_day[i];
    }   
    
  }

  av_nov = sum_nov/dates;           /* 11月の平均気温の計算 */

  

  printf("\n\nTemperature  November/2003 at Akita\n"); 	
  printf("------------------------------------\n");
  printf(" day     max     min    average \n");
  printf("====================================\n");
  
  for(i=1; i<=dates; i++){
    printf("%3d     %5.1lf   %5.1lf   %5.1lf\n",
	   i, max_day[i], min_day[i], av_day[i]);
  }

  printf("------------------------------------\n\n"); 

 
  printf("max(Nov.)     = %5.1lf\n", max_nov);
  printf("min(Nov.)     = %5.1lf\n", min_nov);
  printf("average(Nov.) = %5.1lf\n\n", av_nov);
  
  
  return 0;	
  
}

数値ファイルの清書

#include <stdio.h>

int main(void){
  FILE *fp_read, *fp_write;
  int data[4][8], row, column;
  int sum[8];
  int i, j;

  /* --------------- 行と列のサイズの設定 ----------------------*/

  column = 4;
  row = 8;


  /* --------------- ファイルのオープン ------------------------*/

  if((fp_read=fopen("/tmp/1e/read1.txt","r"))==NULL){
    printf("can not open the file\n");
    return 1;
  }


  /* --------------- ファイルからデータを読み込む ---------------*/
  
  for(i=0; i<=column-1; i++){
    for(j=0; j<=row-1; j++){
      fscanf(fp_read, "%d", &data[i][j]);
    }	
  }
  
  /* --------------- ファイルのクローズ ------------------------*/

  fclose(fp_read);

  
  /* --------------- 合計の計算 ------------------------------*/

  for(i=0; i<=row-1; i++){           /* iは列数を表す */
    sum[i]=0;                        /* 初期化           */
    for(j=0; j<=column-1; j++){      /* iは行数を表す    */       
      sum[i] += data[j][i];          /* 列の和の合計 */
    }
  }
 
  /* --------------- ファイルのオープン ------------------------*/

  if((fp_write=fopen("result.txt","w"))==NULL){
    printf("can not open the file\n");
    return 1;
  }

 
  /* --------------- ファイルへデータを書き込む -----------------*/
  
  for(i=0; i<=column-1; i++){
    for(j=0; j<=row-1; j++){
      fprintf(fp_write, "%5d\t", data[i][j]);
    }
    fprintf(fp_write, "\n");
  }

  fprintf(fp_write,
   "----------------------------------------------------------------\n"
	  );
 
  for(j=0; j<=row-1; j++){
    fprintf(fp_write, "%5d\t", sum[j]);
  }

   
  /* --------------- ファイルのクローズ ------------------------*/

  fclose(fp_write);
  
  return 0;	
  
}

アクセスカウンター

#include <stdio.h>

int main(void){
  FILE *fp;
  int access;

  /*--------------- ファイルのオープン(読み込みモード) ------------------------*/

  if((fp=fopen("/tmp/1e/up.log","r"))==NULL){
    printf("can not open the file\n");
    return 1;
  }
 
  fscanf(fp, "%d", &access);    /*-- ファイルからデータを読み込む --*/
  
  fclose(fp);                   /* -- ファイルのクローズ --*/



  /*--------------- 実行回数の表示 -----------------------------------------*/

  printf("%d 回目の実行です\n", access);


  /*--------------- ファイルのオープン(書き込みモード) ------------------------*/

  if((fp=fopen("/tmp/1e/up.log","w"))==NULL){
    printf("can not open the file\n");
    return 1;
  }
 
  fprintf(fp, "%d",access+1);     /*-- ファイルへデータを書き込む --*/
  
  fclose(fp);                     /*-- ファイルのクローズ --*/

  
  return 0;	
  
}

総合応用問題

プログラム

きれいなプログラムではありませんが、みなさんが学習した範囲で、プログラムを書くとなると以下のようになるでしょう。もう少し、学習が進んで、いろいろなテクニックを学ぶと、もう少し分かりやすいプログラムが書けるでしょう。

#include <stdio.h>

int main(void){
  FILE *fp;
  int seki[100];
  int a_seki, b_seki, c_seki;
  int a_kakaku, b_kakaku, c_kakaku;
  int a_kuseki, b_kuseki, c_kuseki;
  int yoyaku_seki, ryokin;
  int i;

  /* --------------- 席の数と価格 ----------------------*/

  a_seki=10;
  b_seki=20;
  c_seki=50;

  a_kakaku = 5000;
  b_kakaku = 4000;
  c_kakaku = 3700;


  /* --------------- ファイルのオープン ------------------------*/

  if((fp=fopen("zaseki.txt","r"))==NULL){
    printf("can not open the file\n");
    return 1;
  }


  /* --------------- ファイルからデータを読み込む ---------------*/
  
  for(i=0; i<=a_seki+b_seki+c_seki-1; i++){
    fscanf(fp, "%d", &seki[i]);
  }	

  
  /* --------------- ファイルのクローズ ------------------------*/

  fclose(fp);


  /* --------------- 空席のカウント ----------------------------*/

  a_kuseki=0;
  b_kuseki=0;
  c_kuseki=0;

  for(i=0; i<=a_seki-1; i++){
    if(seki[i]==1) a_kuseki++;
  }

  for(i=a_seki; i<=a_seki+b_seki-1; i++){
    if(seki[i]==1) b_kuseki++;
  }

  for(i=a_seki+b_seki; i<=a_seki+b_seki+c_seki-1; i++){
    if(seki[i]==1) c_kuseki++;
  }  


  /* --------------- 席の状態の表示 --------------------------------*/

  printf("\n----------------------------------------------------\n");
  printf("席 価格    空席数  空席番号 \n");
  printf("====================================================\n");

  printf("A    %4d   %2d     ",a_kakaku, a_kuseki);
  for(i=0; i<=a_seki-1; i++){
    if(seki[i] == 1){
      printf(" %2d",i);
    }else{
      printf("   ");
    }
    if(i%10 == 9){
      printf("\n");
      if(i!=a_seki-1) printf("                   ");
    }
  }

  printf("B    %4d   %2d     ",b_kakaku, b_kuseki);
  for(i=a_seki; i<=a_seki+b_seki-1; i++){
    if(seki[i] == 1){
      printf(" %2d",i);
    }else{
      printf("   ");
    }
    if(i%10 == 9){
      printf("\n");
      if(i!=a_seki+b_seki-1) printf("                   ");
    }
  }

  printf("C    %4d   %2d     ",c_kakaku, c_kuseki);
  for(i=a_seki+b_seki; i<=a_seki+b_seki+c_seki-1; i++){
    if(seki[i] == 1){
      printf(" %2d",i);
    }else{
      printf("   ");
    }
    if(i%10 == 9){
      printf("\n");
      if(i!=a_seki+b_seki+c_seki-1) printf("                   ");
    }
  }

  printf("----------------------------------------------------\n\n");

  
  /* --------------- 席の予約 -----------------------------------------*/

  do{
    printf("予約したい席?  ");
    scanf("%d", &yoyaku_seki);
    if(0 <= yoyaku_seki && yoyaku_seki <= a_seki+b_seki+c_seki-1){
      if(seki[yoyaku_seki]==0){
	printf("\nすでに予約されています!!\n\n");
      }else{
	break;
      }
    }else{
      printf("\nそのような席の番号は有りません!!\n\n");
    }
  }while(1);

  seki[yoyaku_seki]=0;
  
  if(yoyaku_seki <= a_seki-1){
    ryokin = a_kakaku;
  }else if(a_seki+b_seki <= yoyaku_seki){
    ryokin = c_kakaku;
  }else{
    ryokin = b_kakaku; 
  }

  printf("\n料金は、%d円です\n", ryokin);
  
    
  /* --------------- ファイルのオープン(書き込み) ------------------------*/

  if((fp=fopen("zaseki.txt","w"))==NULL){
    printf("can not open the file\n");
    return 1;
  }


  /* --------------- ファイルへデータを書き込む ---------------*/
  
  for(i=0; i<=a_seki+b_seki+c_seki-1; i++){
    fprintf(fp, "%d\t", seki[i]);
    if(i%10==9) fprintf(fp,"\n");
  }	
  
  /* --------------- ファイルのクローズ ------------------------*/

  fclose(fp);

  return 0;

}

座席のデータ

このプログラムを実行するにあたり、予め次に示すような、座席の予約状況を示すファイルが必要です。

0  1  1  0  1  1  1  1  1  0  
1  0  1  1  1  1  1  1  1  1  
1  1  1  0  1  1  1  1  1  1  
1  1  0  1  1  1  1  1  1  1  
1  1  1  1  0  0  0  1  1  1  
1  1  1  1  1  0  1  1  1  1  
1  1  1  1  1  1  1  1  1  1  
1  1  1  1  1  1  1  1  1  0  

実行結果

プログラムを実行すると、次のように、座席の状況が表示され、そして予約を促すメッセージが表示されます。

----------------------------------------------------
席   価格    空席数  空席番号 
====================================================
A    5000    7          1  2     4  5  6  7  8   
B    4000   18      10    12 13 14 15 16 17 18 19
                    20 21 22    24 25 26 27 28 29
C    3700   44      30 31    33 34 35 36 37 38 39
                    40 41 42 43          47 48 49
                    50 51 52 53 54    56 57 58 59
                    60 61 62 63 64 65 66 67 68 69
                    70 71 72 73 74 75 76 77 78   
----------------------------------------------------

予約したい席?  66
料金は、3700円です


no counter