1-23 rm_com.c

これもイマイチ。
flush...はDRYに反してるっぽいし、buffはグローバル変数だし…。

/*
 * P42 演習1-23
 *   Cプログラムからすべてのコメントを除去するプログラムを書け。
 *   引用符で囲まれた文字列や文字定数を正しく扱うことを忘れないこと。
 *   Cのコメントは入れ子になっていない。
 *
 *         2007/06/17 arikui
 */


#include <stdio.h>

#define TRUE  1
#define FALSE 0

#define BUFF_EMPTY  -64

int buff = BUFF_EMPTY;

int readchar(void){
    int c;
    if (buff == BUFF_EMPTY){
        c = getchar();
    }else{
        c = buff;
        buff = BUFF_EMPTY;
    }
    return c;
}

void unreadchar(int c){
    buff = c;
}



void flush_comment_rest(int print_p){
    int c, t;
    
    while((c = readchar()) != EOF){
        if (print_p) putchar(c);
        if (c == '*'){
            t = readchar();
            if (t == '/') break;
            else unreadchar(t);
        }
    }
    
    if (c == EOF) unreadchar(c);
}


void flush_quotation_rest(int print_p, int q){
    int c;
    while((c = readchar()) != EOF){
        if (print_p) putchar(c);
        if (c == '\\'){
            c = readchar();
            if (c == EOF) break;
            if (print_p) putchar(c);
        }else if (c == q) break;
    }
    
    if (c == EOF) unreadchar(c);
}



int main(void){
    int c, t;
    
    while((c = readchar()) != EOF){
        if (c == '\\'){
            putchar(c);
            if ((t = readchar()) == EOF) unreadchar(t);
                else putchar(t);
        }else if (c == '\'' || c== '"'){
            putchar(c);
            flush_quotation_rest(TRUE, c);
        }else if (c == '/'){
            t = readchar();
            if (t == '*'){
                flush_comment_rest(FALSE);
            }else{
                unreadchar(t);
                putchar(c);
            }
        }else{
            putchar(c);
        }
    }
    
    return 0;
}