Ex10Ans

From Prog0

Jump to: navigation, search

演習第10回

Contents

解答例

A問題

A-1 パイプ、リダイレクション(リダイレクト)

ファイル名: ex10a1.txt

コマンド:

ハンドアウトLec10-13ページに倣えば、

du -s ~/Prog0/* | sort -k 1,1 -nr | head -5 > ex10a1.txt

など。(上の 1,1 は、sort の結果、容量が表示される列位置を表す)

以下は実行例であり、個々の場合による。サイズで降順にソートされていればOK。ディレクトリだけなくファイルも含まれることが多いだろう。

3524    Prog0/Ex12
92      Prog0/Ex11
88      Prog0/Ex10
84      Prog0/Ex07
80      Prog0/Ex05

du -s ~/Prog0/* | sort -k 1,1 -nr | head -5 > ex10a1.txt

A-2 二次元配列、標準エラー出力

ファイル名: ex10a2.c

#include <stdio.h>
#define GYO 2
#define RETSU 3

int main(){
  
  int i,j,k;
  int data,mat[GYO][RETSU];
  int MAX=GYO*RETSU;
   
  k=0;
  while(k<MAX){
    i=k/RETSU;
    j=k%RETSU;
    printf("%d行%d列の要素の値を正の整数で入力してください\n",i+1,j+1);
    scanf("%d",&data);
        
    if (data <0){
      fprintf(stderr,"Error!負の値が入力されました\n");
      break;
    }
    mat[i][j]=data;
    k+=1;
  }
  if (data >=0){
    printf("行列の値は\n");
    for (i=0; i< GYO; i++){
      for (j=0; j < RETSU; j++){
        printf("%d ",mat[i][j]);
      }
      printf("\n");
    }
  }
  return 0;
}

B問題

B-1 成績処理プログラム

ファイル名: ex10b1.c

#include <stdio.h>
#define SUBJ 9
#define NUM 20

int main()
{
  int score[NUM][SUBJ];
  double stuave[NUM], subjave[SUBJ];
  int i, j, subjno, no;

  /* 初期化 */
  for (i=0; i<NUM; i++) stuave[i]=0;
  for (j=0; j<SUBJ; j++) subjave[j]=0;

  /* 入力 */
  scanf("%d%d",&subjno, &no);
  printf("科目数:%d, 学生数:%d\n",subjno, no);
  for (i=0; i<no; i++) {
    for (j=0; j<subjno; j++) {
      scanf("%d", &score[i][j]);
      stuave[i] += score[i][j];
      subjave[j] += score[i][j];
    }
  }

  /* 平均処理 */
  for (i=0; i<no; i++) {
    stuave[i] /= subjno;
  }
  for (j=0; j<subjno; j++) {
    subjave[j] /= no;
  }

  /* 表示 */
  for (i=0; i<no; i++) {
    for (j=0; j<subjno; j++) {
      printf("%3d   ",score[i][j]);
    }
    printf(":%5.1f\n",stuave[i]);
  }
 
  for (j=0; j<subjno; j++) {
    printf("%5.1f ", subjave[j]);
  }
  printf("\n");
  return 0;
}

B-2 標準エラー出力を使ったプログラム

ファイル名: ex10b2.c

#include <stdio.h>

int main()
{
  int num, rev_num;

  while (1) {
    fprintf(stderr, "Enter a number: ");
    scanf("%d", &num);
    if (num == 0) break;
    if (num < 0) {
      fprintf(stderr, "An error occurred!\n");
      break;
    }
    for (rev_num = 0; num > 0; num /= 10) {
      rev_num = rev_num*10 + num%10;
    }
    printf("%d\n", rev_num);
  }

  return 0;
}

B-3 画像の上下反転

ファイル名: ex10b3.c

/* 上下反転 */
/*
 *
 *   pgm形式の画像データを受け取って,上下反転する。
 *
 *   終了コード
 *     0 : 正常終了
 *     1 : 入力データの形式がおかしい
 *     2 : 入力データの画素数または階調が範囲外
 *     3 : 入力データがおかしいかデータが揃わないうちに
 *         EOFになった
 *     4 : 入力データの画素の値が範囲外
 *
 */
#include <stdio.h>
#include <stdlib.h>

#define MSIZE 800

int main()
{
  int dat[MSIZE][MSIZE];
  int i, j, width, height, maxval;

  /* 入力 */
  /* ファイル形式のチェック                     */
  /* この部分はプログラミング入門の範囲を越えて */
  /* いるので、このまま使って下さい。           */
  if (getchar() != 'P' || getchar() != '2'){
    fprintf(stderr, "データの形式が違います\n");
    exit(1);
  }
 
  /* x,yそれぞれの画素数を得る */
  scanf("%d %d", &width, &height);
  /* Maxval(白の値)を得る */
  scanf("%d",&maxval);

  /* 画素数が範囲外の場合 */
  if (width < 1 || height < 1 || width > MSIZE || height > MSIZE){
    fprintf(stderr, "設定サイズが範囲外です\n");
    exit(2);
  }
  /* Maxvalが範囲外 */
  if (maxval < 1 || maxval >= 65536){
    fprintf(stderr, "階調が範囲外です\n");
    exit(2);
  }

  /* 実際のデータ入力 */
  for (i = 0; i < height; i++){
    for (j = 0; j < width; j++){
      /* scanf入力データがおかしいかEOFになった場合 */
      if(scanf("%d",&dat[i][j]) != 1){
        fprintf(stderr, "データ入力に異常があります\n");
        exit(3);
      }
      /* データが範囲外 */
      if(dat[i][j] < 0 || dat[i][j] > maxval){
        fprintf(stderr, "データが異常でした\n");
        exit(4);
      }
    }
  }
  /* これより上はどのプログラムもほぼ同じ */

  /* 出力 */
  /* 最初にP2とx,yの画素数、Maxvalを出力 */
  printf("P2\n");
  printf("%d %d\n", width, height);
  printf("%d\n", maxval);

  /* 実際のデータ出力 */
  for (i = 0; i < height; i++){
    for (j = 0; j < width; j++){
      printf("%2d ",dat[height-1-i][j]);
      /*
         必須ではないが、テキストデータとして画像ファイルを見やすくするには、適宜改行をいれる。
         例えば以下の処理では、20個のデータごとに改行する。 
         if (j%20==19) printf("\n"); 
      */
    }
    printf("\n");
  }
  return 0;
}

赤で示されている部分がこのプログラムの重要なポイントです

Extra問題

E-1 コントラストを上げる

ファイル名: ex10e1.c

/* コントラスト向上 */
/*
 *   gcont.c
 *
 *   pgm形式の画像データを受け取って,画像の
 *   コントラストをあげる
 *
 *   終了コード
 *     0 : 正常終了
 *     1 : 入力データの形式がおかしい
 *     2 : 入力データの画素数または階調が範囲外
 *     3 : 入力データがおかしいかデータが揃わないうちに
 *         EOFになった
 *     4 : 入力データの画素の値が範囲外
 *
 */
#include <stdio.h>
#include <stdlib.h>

#define MSIZE 800
#define COEF 1.5L
int main()
{
  int dat[MSIZE][MSIZE];
  int i, j, width, height, maxval;
  int maxval2;

  /* 入力 */
  /* ファイル形式のチェック                     */
  /* この部分はプログラミング入門の範囲を越えて */
  /* いるので、このまま使って下さい。           */
  if (getchar() != 'P' || getchar() != '2'){
    fprintf(stderr, "データの形式が違います\n");
    exit(1);
  }
 
  /* x,yそれぞれの画素数を得る */
  scanf("%d %d", &width, &height);
  /* Maxval(白の値)を得る */
  scanf("%d",&maxval);

  /* 画素数が範囲外の場合 */
  if (width < 1 || height < 1 || width > MSIZE || height > MSIZE){
    fprintf(stderr, "データが大きすぎます\n");
    exit(2);
  }
  /* Maxvalが範囲外 */
  if (maxval < 1 || maxval >= 65536){
    fprintf(stderr, "階調が範囲外です\n");
    exit(2);
  }

  /* 実際のデータ入力 */
  for (i = 0; i < height; i++){
    for (j = 0; j < width; j++){
      /* scanf入力データがおかしいかEOFになった場合 */
      if(scanf("%d",&dat[i][j]) != 1){
        fprintf(stderr, "データ入力に異常があります\n");
        exit(3);
      }
      /* データが範囲外 */
      if(dat[i][j] < 0 || dat[i][j] > maxval){
        fprintf(stderr, "データが異常でした\n");
        exit(4);
      }
    }
  }
  /* これより上はどのプログラムもほぼ同じ */

  /* コントラストの変更処理 */
  maxval2 = maxval/2; /* maxval/2を一旦変数maxval2に入れておく */

  for (i = 0; i < height; i++){
    for (j = 0; j < width; j++){
      if(dat[i][j] >= maxval2) {
        dat[i][j] *= COEF;
        if(dat[i][j] > maxval) dat[i][j] = maxval; /* Maxvalを超えた場合の処理 */
      }
      else dat[i][j] /= COEF;
    }
  }

  /* 出力 */
  /* 最初にP2とx,yの画素数、Maxvalを出力 */
  printf("P2\n");
  printf("%d %d\n", width, height);
  printf("%d\n", maxval);

  /* 実際のデータ出力 */
  for (i = 0; i < height; i++){
    for (j = 0; j < width; j++){
      printf("%2d ",dat[i][j]);
      /*if (j%20==19) printf("\n");*/ /* 改行処理 */
    }
    printf("\n");
  }
  return 0;
}

赤で示されている部分がこのプログラムの重要なポイントです

Personal tools