K&R演習[1-13]

課題

入力した単語の長さをヒストグラムにしてプリントするプログラムを書け。

解答

#include <stdio.h>

const int CNT = 10;         // 出現回数
const int LENGTH = 20;      // 文字列長

void print_histogram(int *cnt); // ヒストグラム表示

/**
 * @fn      main
 * @brief   単語の長さをヒストグラムにして表示する
 * @param   なし
 * @return  なし
 * @detail
 */
int main(void)
{
    int c, cnt[LENGTH], i, tmp = 0;

    for (i = 0; i < LENGTH; i++) {
        cnt[i] = 0;
    }

    while ((c = getchar()) != EOF) {        // ファイル終端まで

        if ((c == ' ') || (c == '\t')) {    // タブまたは空白であれば
            cnt[tmp]++;                     // 文字数別の計数を足す
            tmp = 0;
        } else if (c == '\n') {             // 改行でヒストグラム印字
            cnt[tmp]++;                     // 文字数別の計数を足す
            print_histogram(cnt);           // ヒストグラム印字

            // 次に備えて初期化
            for (i = 0; i < LENGTH; i++) {  // 
                cnt[i] = 0;                 // 計数配列の初期化
            }
            tmp = 0;                        // 文字計数の初期化

        } else if ((c != ',') && (c != '.')){   // コンマやピリオドでなければ
            tmp++;                              // 単語として文字数を計測
        }
    }
}

/**
 * @fn      ヒストグラム印字
 * @brief   
 * @param   なし
 * @return  なし
 * @sa      
 * @detail  
 */
void print_histogram(int *cnt)
{
    char i, j;

    printf("------- histogram -------\n");  // タイトル
    for (i = CNT; i >= 1; i--) {            // 回数
        printf("%2d", i);                   // 縦軸
        
        for (j = 1; j < LENGTH; j++) {
            if (*(cnt + j) >= i) {          // 現在の回数以上であれば
                printf("  *");              // 文字を表示する
            } else {
                printf("   ");              // 空白を表示する
            }
        }
        printf("\n");
    }

    // 横軸(文字列長)
    printf("  ");
    for (j = 1; j < LENGTH; j++) {          // 文字列長
        printf("%3d", j);                   // 
    }
    printf("\n");

#if 0
    // デバッグ用
    for (i = 0; i < CNT; i++) {
        printf("%d:%d\n", i, cnt[i]);
    }
#endif
}


実行内容

I have often thought it would be a blessing if each human being were to become blind and deaf for a few days at some time during his early life.

実行結果

------- histogram -------
10
 9
 8           *
 7           *
 6           *  *
 5     *     *  *
 4     *  *  *  *
 3  *  *  *  *  *
 2  *  *  *  *  *  *
 1  *  *  *  *  *  *  *  *
    1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19