第1章 「やさしい入門」 1.5
 文字入出力 1.5.4
 単語のカウント

2021年9月4日

今回は単語、行、文字の個数を数えるプログラムを作成します。
ここでは単語は空白やタブ、改行を含まない任意の文字と定義します。
つまりこれらの文字コードとそれ以外をを見つければ単語の認識が可能になります

プログラムの目的

単語、行、文字の個数を数える

ソースコード

解説

K&Rの本のソースコードから多少変更しています。
コメントも入れて見やすくしました。
この程度の長さのソースコードではコメントが無くても理解出来ますが数万行を超える長さのプログラムではコメントが無いと理解出来なくなります。
読者の皆様も、早い段階でコメントを入れる習慣をつけてください。
コメントの入れ方にもコツがあり、ソースコードをみれば判るようなコメントは不要です。
例えばサンプルプログラムで++char_ctの行がありますが、ここに「char_ctをインクリメントする」のようなコメントは不要です。

①bool in_flag = false; //単語の中にいることを示すフラグ(true=単語の中)
この書式はK&RのANSI規格では無かったと思います。
boolとは真と偽の二値を扱うために用意されている型になりブール型とかブーリアン型と呼びます。
二値の場合、K&Rのようにintを使うのでは無くこちらを利用することをおすすめします。
(尚、windowsのプログラムでは伝統的にBOOL型を利用しますので頭の隅にでも置いておいて下さい)

二値のデータはフラグとも呼ばれます。
コメントではフラグと表現しています。こちらの呼び方が一般的でしょう。

② int char_ct = 0; //文字カウンタ
int line_ct = 0; //行のカウンタ
int word_ct = 0; //単語のカウンタ

ここでも本のサンプルと異なり、複数行に分けて記述しています。
理由がありそれぞれの変数の意味をコメントしたいためです。
定義と変数の初期化を同時に行っています。

③while ((c = getchar()) != EOF) {
前回のサンプルまでは読者の皆様が混乱しないように、あえてwhile()の中に式を書きませんでした。
whileには慣れて来たと思いますので本と同様の書式にしました。
こちらの方が1行に簡潔に書けますが、好みですので前回までの書き方でも構いません。
注意として式は一つにしましょう、いくつでも書けるのですが見にくくなります。

④++char;
ここで入力キーのカウントを行っています。

⑤ if (c == '\n’) { //改行判定
++line_ct;
}
改行判定して改行ならカウントしています。

⑥ if (c == ' ' || c == '\n’ || c == '\t’) { //空白、改行、タブのどれかと同じか判定
//これは単語の中にいるか、外かを判定するため
//どれかと同じなら単語の外と判定出来る

ちょっとコメントがしつこいですが、読者の皆様に理解しやすくしたつもりです。
今回初めて出てきた||は、OR条件を意味します。
ここではcの値が’ 'または’\n’または’\t’なら真になります。

⑦’\t’
これはTABコードを意味します。
スペースは’ 'だったりAは’A’なのになぜTABは’\t’なのか不思議に思われた方も多いのではないでしょうか?
そういう意味では改行も同じですね。
実はTABや改行は、特殊文字としてテキスト入力が出来ません。
このような文字では\記号+1文字で特殊文字を表現します。
他にもたくさんの特殊文字がありますが、必要な時にまたご紹介しますね。

ここは\が付いているエスケープシーケンスがあると覚えておいてください。

⑧in_flag = false;
フラグ(ブーリアン型)を偽にしています。
反対に真にするのは
in_flag = true

⑨コメントのテクニック
今回のプログラムがわかり難くなるポイントして単語の外側にいるのか内側にいるのかを判定して処理をしているところだと思います。
その部分を判りやすくするため、分岐の頭にコメントを入れてあります。
「単語の外にいる」「単語の内側にいる」がそれになります。
このコメントで制御の大枠がソースコードを読まなくても直感的に理解出来るようになります。

動作の確認

簡単に動作確認してみましょう。

ABCを押して改行、defスペースghiと押して改行、最後にCTRL+Zと押してエンター。
どのようになりましたか?

行数は2、単語数は3、文字数は12となれば正解です。

 

今回はここまで

※本プログラム教室はK&Rの「プログラミング言語C」をベースに進めています。