読者です 読者をやめる 読者になる 読者になる

1-18.c

演習 1-18 各入力行から、行の後のブランクやタブを取り除き、かつ空白行は全て削除するようなプログラムを書け。

#include <stdio.h>
#define MAXBLANK 1000

#define TRUE 1
#define FALSE 0

main()
{
        int c;
        int i;
        /* 空白文字の一時保存 */
        int blcount = 0;
        char blmem[MAXBLANK];
        int prevblank = FALSE;
        int prevnl = TRUE;

        while ((c = getchar()) != EOF) {
                if (c == ' ' || c == '\t') {
                        /* 空白文字保存 */
                        blmem[blcount++] = c;
                        prevblank = TRUE;
                } else if (c == '\n') {
                        /* 一時記録されている空白をリセット */
                        if (prevblank == TRUE)
                                blcount = 0;
                        /* 空行が続くのを回避 */
                        if (prevnl != TRUE)
                                putchar(c);
                        prevblank = FALSE;
                        prevnl = TRUE;
                } else { /* (c == 通常の文字) */
                        /* 一時記録されている空白を出力しリセット */
                        if (prevblank == TRUE) {
                                for (i = 0; i < blcount; ++i)
                                        putchar(blmem[i]);
                                blcount = 0;
                        }
                        putchar(c);
                        prevnl = prevblank = FALSE;
                }
        }
}

英語スキルの無さはプログラミングにおいて障壁となるな。。変数名が考えられないし、本当はコメントも英語が望ましい。

そしてタブとスペースが含まれるテキストファイルをテスト用に用意。
以下は分かりやすいように、テスト用ファイルのスペースとタブをそれぞれ-,=に置き換えて視覚化した結果。trコマンドは文字の置き換えをする。

$ tr ' ''\t ' -= < test.txt
==a-==
a=a-
=a
=


元のファイルの一行目は
タブ タブ a スペース タブ タブ 改行

となっているのがわかる。例えば一行目であればaの後ろの「-==」、すなわち「スペース タブ タブ」の部分が消えればいいわけだ。
このファイルを1-18に読み込ませ、さらに視覚化する。
$ ./a.out < test.txt | tr ' ''\t' -=
==a
a=a
=a

不要な空白文字や改行が掃除されているし必要な文字は消えていないのでOK