C言語ケーススタディ ファイルの行数・単語数をカウントするプログラム1




2014年10月より個人の方を対象に、Study C無料提供を開始しました。
C言語を勉強中の方は、学習・教育に最適なC言語インタープリタのStudy Cを使ってみてください(個人の方は無料です)。
大学・高専・高校などの教育機関での採用実績も多数あるロングセラー商品Study Cが、個人向けに無料提供を始めました。
インタープリタの手軽さに加え、ゲームや3Dタートルグラフィックで楽しく勉強したりと、C言語の学習を強力にサポートします。
ブロック崩しゲーム 3Dツリー クリスマスツリー
また、このようなボタンの用意されているページでは、掲載しているプログラムをStudy Cに直接ロードし実行したりすることができます。
Study Cにロードする Study Cにロードし編集する Study Cにロードし実行する
Study C無料利用についての詳細は、このページを参照してください。



ファイルの行数・単語数をカウントするコマンドとしてはUNIXのwc(word count)コマンドが有名です。今回はこれと類似したコマンドを作成します。 ファイルからの入力にはfgets()関数を使うことが多いですが、今回はfread()関数を使用します。 fgets関数を使用しない理由はこの関数が行単位の読み込みを行うのですが、1行のサイズが大きい行が存在すると処理が煩雑になるためです。

単語は次の規則でカウントすることにします。
(1)空白文字で区切られた文字が存在する場合
(2)0x20未満のアスキーコードで区切られた文字が存在する場合
(3)区切り文字が連続する場合は単語としてカウントしない

#include <stdio.h>

void    main(int argc, char *argv[])
{
        FILE    *fp;
        char    buff[1024];
        unsigned char
                *pntr,
                *wp;

        int     num, blank;

        unsigned long
                character, word, line;

        if(argc != 2){
                printf("コマンドの入力形式が間違っています.\n");
                return;
        }

        fp = fopen(argv[1], "r");
        if(fp == NULL){
                printf("ファイルがオープンできません[%s].\n", argv[1]);
                return;
        }

        blank = 0;
        character = word = line = 0;
        while((num = fread(buff, 1, 1024, fp)) > 0){
                for(wp = buff; num > 0; num--,wp++){
                        if(*wp <= ' '){
                                if(*wp == '\n'){
                                        line++;
                                        character++;
                                }
                                if( !blank )
                                        word++;
                                blank = 1;
                                character++;
                        }
                        else{
                                blank = 0;
                                character++;
                        }
                }
        }
        printf("%7ld %7ld %7ld %s\n", line, word, character, argv[1]);
        fclose(fp);
}

このプログラムは、"run ファイル名"という形式で実行します。

関連するC言語講座は以下になります。解らない項目があれば参照してください。
コマンドラインからのファイル名の取得について:C言語入門 第17回 コマンドラインからのパラメータ受け取り
ファイルのオープン/クローズについて:C言語入門 第14回 ファイル読み書き1(ファイル読み書きの基礎)
文字コード(アスキーコード)について:C言語入門 第9回 文字・文字列の使い方

このプログラムのメインの処理は、while文の内部になります。主な処理は以下の通りです。
(1)while文の条件式としてfread()関数を呼び出しファイルの内容を読み込みます(最大1024バイト)。
(2)読み込んだ文字列をfor文で位置文字ずつ処理します。
(3)文字が'\n'(改行文字)なら行数をカウントする変数lineを1増加させます。 (4)文字が' '(空白文字)以下の文字コード(区切り文字)なら単語数をカウントする変数wordを1増加させます。 区切り文字が続く場合(blank変数が1かで判断)はカウントしません。
(5)文字が' '(空白文字)より大きい文字コードならblank変数を0にします(区切り文字ではないので)。
(6)何れの文字でも文字数をカウントする変数characterを1増加させます。
(7)最後に各変数(line、word、character)などの値を表示します。