K&Rを読もう(17) 演習 1-24 括弧の釣合(1)

1章の最終問題です。激しくムズい!!


括弧の釣合が取れているかチェックする問題。

これだけなら良いのだが「引用符・2重引用符・コメントがあった場合の処理も追加せよ」という難問。


とりあえず問題を切り分けよう。引用符チェック無しで解く。

#include <stdio.h>
#include <stdlib.h>

#define MAX_BUFFER 1024

void err_exit(void)
{
    fprintf(stderr, "釣合が取れてません。\n");
    exit(EXIT_FAILURE);
}

int main(void)
{
    int c,d;
    int i = 0;
    char buffer[MAX_BUFFER];
    
    while ((c = getchar()) != EOF) {
        if (c == '(' || c == '{' || c == '[')
            buffer[i++] = c;
        else if (c == ')' || c == '}' || c == ']') {
            if (i <= 0)
                err_exit();

            d = buffer[--i];
            printf("level %2d : [%c:%c]\n", i + 1, d, c);
            if ( d == '(' && c != ')' ||
                 d == '{' && c != '}' ||
                 d == '[' && c != ']')
                err_exit();
        }
    }
    if (i != 0)
        err_exit();
    else
        printf("OK\n");


    exit(EXIT_SUCCESS);
}

スタック方式でチェックします。オーバーフローはチェックしてない(汗

テスト

前回の問題ならチェックは通る。

% ./ex-1-24 < ex-1-23.c
level  1 : [{:}]
level  1 : [(:)]
level  2 : [(:)]
level  2 : [(:)]
level  3 : [(:)]
level  3 : [(:)]
level  3 : [(:)]
level  4 : [(:)]
level  3 : [{:}]
level  3 : [(:)]
level  3 : [(:)]
level  2 : [{:}]
level  2 : [(:)]
level  1 : [{:}]
OK

今回のソースでチェックすると・・・。

% ./ex-1-24 < ex-1-24.c
level  1 : [(:)]
level  2 : [(:)]
level  2 : [(:)]
level  1 : [{:}]
level  1 : [(:)]
level  2 : [[:]]
level  4 : [(:)]
level  3 : [(:)]
level  2 : [(:)]
level  6 : [[:)] // else if (c == ')' || c == '}' || c == ']') {
                                   ^コレ
釣合が取れてません。

引用符の中に括弧があるとうまくいかない。

まだまだ続く。