ステートマシンを作ろうだいにっかい
のみのこしワインと共に!!!
さてさて前回は、http://d.hatena.ne.jp/ore_de_work/20090320 ステートマシンって便利だねー
っとところで終わりましたが、
実際に、改行コードのステートマシンを着くってみましょー
以下は行をCRLFでスプリットするサンプルです。
#include <stdio.h> #include <string.h> void LogDisp( const char *r ) { printf("%s\n", r); } int LogMachine( const char* msg ) { char *p, *r, *d; d = strdup(msg); p = r = d; for(;;) { if( *p == '\0' ) goto DISP; if( *p == '\r' || *p == '\n' ) { *p = '\0'; p++; if( *p == '\r' && *(p + 1) == '\n' ) p++; goto DISP; } p++; continue; DISP: LogDisp( r ); if( *p == '\0' ) break; p++; if( *p == '\0' ) break; r = p; continue; } free(d); return 0; } int main(void) { LogMachine("123\n456\r\n789\naaaa"); return 0; }
上記をステートで書き直すと以下のようになります。
#include <stdio.h> #include <string.h> //#define DEGUG(x) x #define DEGUG(x) #define START 0 #define RUN 1 #define DISP_NEXT_END 2 #define SPLIT_CR 3 #define SPLIT_LF 4 #define DISP_NEXT_RUN 5 #define END 6 char *disp_state[ ] = { "START " , "RUN " , "DISP_NEXT_END " , "SPLIT_CR " , "SPLIT_LF " , "DISP_NEXT_RUN " , "END " , "" , "" , "" , }; void LogDisp(char *r ) { printf("%s\n", r); } int LogMachine(char* msg) { char *p, *r, *d; int state = START; for(;;) { DEGUG(printf(" " "[%s(%u/%u)]\n", disp_state[state], r - d , p - d )); switch( state ) { case START: d = strdup(msg); p = r = d; state = RUN; break; case RUN: if( *p == '\0' ) { state = DISP_NEXT_END; } else if( *p == '\r' ) { state = SPLIT_CR; } else if( *p == '\n' ) { state = SPLIT_LF; } else { p++; } break; case SPLIT_CR: *p = '\0'; p++; state = DISP_NEXT_RUN; if( *p == '\n' ) state = SPLIT_LF; /* CRLF */ break; case SPLIT_LF: *p = '\0'; p++; state = DISP_NEXT_RUN; break; case DISP_NEXT_END: LogDisp( r ); LogDisp( r ); r = p; p++; state = END; break; case DISP_NEXT_RUN: LogDisp( r ); r = p; p++; state = RUN; break; case END: free(d); return 0; break; } } return 0; } int main(void) { LogMachine("123\n456\r\n789\naaaa"); return 0; }
このコード、どちらも
# gcc hoge.c && ./a.out
123
56
89
aaa
となります。
さて、此処から、ESC や ^h を判定したりするルーチンをついかするばーい
どっちのほうが らくかーらくかーな
うわ
どっちもおんなじだorz
べ、、べつにあんたの(ry