- ベストアンサー
C言語のエラー処理について
- C言語のエラー処理について質問です。
- 適切なエラーメッセージが表示されない場合の修正方法を教えてください。
- 入力エラーの場合には「input error」と表示されるようにしたいです。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
#include <stdio.h> #include <time.h> #include <string.h> #include <stdlib.h> #define CALC (3) #define FROM_YEAR (1900) #define MAX_LINE (1000) #define MAX_ROW (1000) float calc_proc(int* n1, char op, int n2, float* ans) { switch (op) { case '+': *ans = (float)*n1 + n2; break; case '-': *ans = (float)*n1 - n2; break; case '*': *ans = (float)*n1 * n2; break; case '/': if (n2 == 0) { /*puts("input error");*/ return 1; } *ans = (float)(float)*n1 / n2; break; default: /*printf("input error");*/ return 1; break; } return 0; } int cmp_u(const void* a, const void* d) { return strcmp((char*)a, (char*)d); } int cmp_d(const void* a, const void* d) { return strcmp((char*)d, (char*)a); } int main() { int num1, num2; char op; float answer; int i; FILE* fp; char e[11]; char sin[MAX_LINE][MAX_ROW]; char ad[8]; fp = fopen("log.txt", "a+"); if (fp == NULL) { printf("ファイルオープン失敗\n"); return -1; } while (1) { if (scanf("%d%c%d", &num1, &op, &num2) != 3) { puts("input error"); return 1; } scanf("%*[^\n]%*c"); /*入力バッファを捨てる*/ /*calc_proc(&num1, op, num2, &answer);*/ if (calc_proc(&num1, op, num2, &answer) != 0) { puts("input error"); return 1; } time_t t = time(NULL); struct tm* tm = localtime(&t); printf("%d/%02d/%02d ", tm->tm_year + FROM_YEAR, tm->tm_mon + 1, tm->tm_mday); printf("%02d:%02d:%02d ", tm->tm_hour, tm->tm_min, tm->tm_sec); printf("%d%c%d,%f\n", num1, op, num2, answer); fprintf(fp, "%d/%02d/%02d ", tm->tm_year + FROM_YEAR, tm->tm_mon + 1, tm->tm_mday); fprintf(fp, "%02d:%02d:%02d ", tm->tm_hour, tm->tm_min, tm->tm_sec); fprintf(fp, "%d%c%d,%f\n", num1, op, num2, answer); printf("計算を続けますか?"); if (scanf("%s", e) == 1) { if (strcmp(e, "no") == 0) { break ; } } else break; scanf("%*[^\n]%*c"); /*入力バッファを捨てる*/ } fclose(fp); fp = fopen("log.txt", "r"); if (fp == NULL) { printf("ファイルオープン失敗\n"); return -1; } int cnt = 0; for (i = 0;i < MAX_LINE;i = i + 1) { if (fgets(sin[i], sizeof(sin[0]), fp)) ++cnt; else break; } fclose(fp); printf("ASC or DESC: "); scanf("%s", ad); scanf("%*[^\n]%*c"); /*入力バッファを捨てる*/ if (strcmp(ad, "ASC") == 0) { qsort(sin, cnt, sizeof(sin[0]), cmp_u); } else { qsort(sin, cnt, sizeof(sin[0]), cmp_d); } for (i = 0;i < cnt;i = i + 1) { printf("%s", sin[i]); } return 0; } ----- scanfは、意図しない入力が行われると、入力バッファに入力した物が残り、次に行われるscanfが想定外の動作をするので、扱いが非常に難しいので注意。 また、意図しない入力があったのを判定するのに、scanfの戻り値を積極的に使用する。 あと、エラー表示は「呼んだ関数の中」や「呼んで帰って来たあと」など、複数個所で行ってはいけない。 input errorinput errorinput error という表示になった理由は scanf("%d%c%d", &num1, &op, &num2); calc_proc(&num1, op, num2, &answer);←ここで1回 if (calc_proc(&num1, op, num2, &answer) != 0) {←ここで1回 puts("input error");←ここで1回 のように、3回エラー表示しているから。 input errorinput errorinput error と input error input error input error のように、改行の有る無しの違いは、片方の1、2回目は printf("input error"); になってて改行しないけど、もう片方の1、2回目は puts("input error"); になってて勝手に改行されるから。 つまり、整数以外の入力では printf("input error"); printf("input error"); puts("input error"); の3つが実行されて input errorinput errorinput error(改行) の表示になり、ゼロ除算の入力では puts("input error"); puts("input error"); puts("input error"); の3つが実行されて input error(改行) input error(改行) input error(改行) の表示になる。
その他の回答 (3)
- AsarKingChang
- ベストアンサー率46% (3467/7474)
calc_proc(&num1, op, num2, &answer); if (calc_proc(&num1, op, num2, &answer) != 0) { puts("input error"); ここもか。。 !=0が返される条件では、行った先の関数が、 puts("input error"); も出力してしまうので、3重になりますね。 float calc_proc(int* n1, char op, int n2, float* ans) { さらに、返り値がfloatなのに、 returnが1や0になってます。 1.0f や0f ではあるものの、この程度を返すなら 普通は、intでいいでしょうね。 なので、 int err; err=calc_proc(&num1, op, num2, &answer); if (err) { でもいいかと、 元々C言語のIF分は0かそれ以外か?なので、 err!=0 は errだけで同じ結果なので。 ひとまずは、これで綺麗になるとは思いますが、 私なら、calc_procに表示物はつけませんね。 バリデーター側で実装すべきとは思いますが。 そんなところです。
- notnot
- ベストアンサー率47% (4900/10358)
scanfの返り値を確認していないからです。 3項目入力するのであれば、返り値が3であることを確認しましょう。 あと、calc_proc を2回続けて呼んでいるのも変ですね。これは致命的ではないですが。 あと、そもそも端末からの入力にscanfを使うのは間違っており、正しいやり方としては、fgets と sscanf を使います。この場合は、sscanfの返り値を確認します。
- AsarKingChang
- ベストアンサー率46% (3467/7474)
今回は超短く回答! puts("input error"); printf("input error"); 2種類混在してますよ~ putsは、printf("text" + "\n")ですから、 printf("input error")こっちを通れば繋がります。 そんだけ!
お礼
ありがとうございました。