atoi、scanf、str系の関数を使わずに入力した数式を計算するプログラムを作っています。
1.数式の入力を求める
2.数式を入力し、enterを押したら(+,-,*/が使用可能)
3.計算結果を表示する
4.1に戻る
5‘q’が入力されたら終了
といったものです。
問題には以下の条件があります。
1.入力した数値の計算はmein関数以外で実施
2.scanf、atoi、str系禁止
3.0除算はの場合エラー処理を行う
4.一行に入力できる演算子は1のみ
5.小数点、()には対応せず数値演算子以外の文字を含んだ場合エラー処理を行う
6.ただし、数値と演算子の間と数式の前後のスペースは許容する(1 23*4はNG)
以上です
ようやく思うとおりに挙動するようになったのですが、もう少し綺麗に書けないかと考えております。
該当のソースコード
C
1#include <stdio.h> 2#include <stdlib.h> 3 4//配列の長さを一度に設定できるように宣言する 5#define STRLEG 16 6 7 8 9//四則演算を行う関数 10int calc(int num1, int num2, char *op){ 11 //演算結果を格納する変数ans 12 int ans; 13 14 //取得した演算記号べつに計算を行う 15 switch(*op){ 16 case '+': 17 ans = num1 + num2; 18 break; 19 case '-': 20 ans = num1 - num2; 21 break; 22 case '*': 23 ans = num1 * num2; 24 break; 25 case '/': 26 ans = num1 / num2; 27 default: 28 break; 29 } 30 //演算結果を返す 31 return ans; 32 33} 34 35 36int main(){ 37 //入力された数式を入れるための変数str 38 char *p, str[STRLEG]; 39 //演算子を格納する変数op 40 char op; 41 //数式の中に現れた数値をカウントする変数countnum 42 int countnum = 0; 43 //数式の中に現れた演算子の数をカウントする変数 44 int kigo = 0; 45 //数式の中で最初に現れる数値を格納する 46 int num1 = 0; 47 //数式の中で2番目に現れる数値を格納する 48 int num2 = 0; 49 //演算結果を入れる 50 int ans; 51 52 //qが入力されるまでループさせる 53 do { 54 //メッセージを表示して数式を入力させる 55 printf("数式を入力してください\n"); 56 57 //入力した数式をstrに入れる 58 fgets(str,sizeof str,stdin); 59 60 //qが入力されたらループを抜ける 61 if(str[0]=='q') break; 62 63 //一文字ずつ読み取り数値と演算子に分ける 64 for (p = str; *p != '\n'; p++ ) { 65 //空白でない場合に処理を行う。 66 if(*p != ' '){ 67 //数値である場合の処理 68 if(*p >= '0' && *p <= '9'){ 69 //カウントする 70 countnum++; 71 /*これから読み取る数値の前に演算子が来ていなければ 72 一つ目の数値として認める*/ 73 if (countnum == 1 && kigo == 0) { 74 //数字以外の文字がくるまで一度に代入する 75 while(*p >= '0' && *p <= '9'){ 76 num1=num1*10+*p-'0'; 77 p++; 78 } 79 p--; 80 //二つめの数値の前に演算子が一つ来ていることを確かめる 81 } else if (countnum == 2 && kigo == 1) { 82 while(*p >= '0' && *p <= '9'){ 83 num2=num2*10+*p-'0'; 84 p++; 85 } 86 p--; 87 //その他はエラー 88 } else { 89 printf("数値の間にスペースを入れないでください\n"); 90 exit(1); 91 } 92 //演算子を読み取ったときの処理 93 }else if(*p == '+' || *p == '-' || *p == '*' || *p == '/'){ 94 kigo++; 95 if(kigo==2){ 96 printf("演算子は二つ以上入れないでください\n"); 97 exit(1); 98 } 99 op = *p; 100 //空白以外で数値・演算子以外の文字は無効 101 }else{ 102 printf("不正な文字が含まれています\n"); 103 exit(1); 104 } 105 } 106 } 107 108 //0除算を行えないようにする 109 if(op=='/'&&num2==0){ 110 printf("0除算はできません。\n"); 111 exit(1); 112 } 113 114 //計算を行う関数calcに二つの数値と演算子を送る 115 ans = calc(num1,num2,&op); 116 //計算結果の出力 117 printf("%d %c %d = %d\n",num1,op,num2,ans); 118 119 //入力された文字列と数値、カウンタを初期化 120 str[STRLEG]; 121 num1 = num2 = kigo = countnum = 0; 122 123 }while(1); 124 125 return 0; 126}
特に文字列を変換する作業に関して、同じ処理を別に書いていることと
数値に変換した後のデクリメントを直したいと考えております。
同じ処理のまとめ方と帳尻合わせのデクリメントを対処する方法
その他何か、お気づきの点があればご教授いただけると幸いです。
よろしくお願いいたします。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/06/24 15:11