Ex10Ans
From Prog0
演習第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; }
赤で示されている部分がこのプログラムの重要なポイントです