/* * インタプリタの例:複数カゴ対応セルフレジ register.c * コンパイル方法:$ cc register.c -o register -Wall * 実行方法: * 1) 対話処理:$ ./register * 2) 一括処理:$ ./register ファイル.reg */ #include #include #include #define BUFLEN 256 // 入力行の最大文字数 #define DELIM " \t\n" // 入力行の区切り文字 int total_price = 0; // 合計金額 int total_number = 0; // 合計数量 int cart_price = 0; // カゴの合計金額 int cart_number = 0; // カゴの合計数量 int cart = 1; // カゴの番号 /* ヘルプ */ void Help() { printf("=====================================\n"); printf(" 複数カゴ対応セルフレジ\n"); printf("=====================================\n"); printf(" 使用方法\n"); printf(" 各商品のお勘定: @ 単価 数量\n"); printf(" 次のカゴへ: next\n"); printf(" お支払いへ: end\n"); printf("=====================================\n"); } /* 金額の勘定 */ void Count(int price, int number) { cart_price += price*number; cart_number += number; } /* 小計の表示とカゴの変更 */ void Subtotal() { printf("--------------------\n"); printf("カゴ#%d小計\n", cart); printf(" 商品数:%10d\n", cart_number); printf(" 金 額:%10d\n", cart_price); total_price += cart_price; total_number += cart_number; cart_price = 0; cart_number = 0; } /* 合計の表示 */ void Total(int cart) { printf("====================\n"); printf("お買上げ合計\n"); printf(" カゴ数:%10d\n", cart); printf(" 商品数:%10d\n", total_number); printf(" 金 額:%10d\n", total_price); } /* メイン */ int main(int argc, char *argv[]) { FILE *fp; // 入力のファイルポインタ char buf[BUFLEN]; // 入力の行文字列 char *cmd; // コマンドの文字列ポインタ char *param; // コマンド引数の文字列ポインタ int price, number; // 単価,数量 int line = 1; // 入力の行番号 if (argc > 1) { // 一括処理 fp = fopen(argv[1], "r"); if (fp == NULL) return (EXIT_FAILURE); } else { // 対話処理 fp = stdin; Help(); } BODY: while (1) { // 言語処理のメインループ if (fp == stdin) printf("コマンド > "); // プロンプト表示 if (fgets(buf, BUFLEN, fp) == NULL) break; // 1行入力 cmd = strtok(buf, DELIM); // 入力行からコマンドを抽出 if (cmd == NULL) continue; // 空行を無視 if (strcmp(cmd, "#") == 0) { // # コマンド ; // コメント行として無視 } else if (strcmp(cmd, "@") == 0) { // @ コマンド if ((param = strtok(NULL, DELIM)) == NULL) goto ERROR; price = atoi(param); // 単価を抽出 if ((param = strtok(NULL, DELIM)) == NULL) goto ERROR; number = atoi(param); // 数量を抽出 // 本来ならatoi()の前にエラー処理(数字列チェック) // も必要だが,今回は気にしないでおく Count(price, number); // 勘定 } else if (strcmp(cmd, "next") == 0) { // next コマンド Subtotal(); // 現在のカゴの小計 cart++; } else if (strcmp(cmd, "end") == 0) { // end コマンド break; // 終了処理へ } else { // コマンド以外 goto ERROR; // エラー処理へ } line++; } Subtotal(); // 現在のカゴの小計 Total(cart); // 合計 if (fp != stdin) fclose(fp); return (EXIT_SUCCESS); ERROR: fprintf(stderr, "!!! 入力エラー !!! [L:%d]\n", line); goto BODY; // とりあえず,エラーでも続行しとく,ことにしとく }