[前へ]   [目次へ]   [次へ]

文字入力型四則演算計算機(C/C++)


今回は、第28回の四則演算計算機の演算種別入力を文字に切り替えてみます。
まずは、第28回のソースを再掲載します。

<  1>
<  2>
<  3>
<  4>
<  5>
<  6>
<  7>
<  8>
<  9>
< 10>
< 11>
< 12>
< 13>
< 14>
< 15>
< 16>
< 17>
< 18>
< 19>
< 20>
< 21>
< 22>
< 23>
< 24>
< 25>
< 26>
< 27>
< 28>
< 29>
< 30>
< 31>
< 32>
< 33>
< 34>
< 35>
< 36>
< 37>
< 38>
< 39>
< 40>
< 41>
< 42>
< 43>
< 44>
< 45>
< 46>
< 47>
< 48>
< 49>
< 50>
< 51>
< 52>
< 53>
< 54>
#include <stdio.h>

int main(void)
{
   
//変数宣言/定義
   
char buf[64]="";//空文字列で初期化
   
int in1=0;//入力1格納変数
   
int in2=0;//入力2格納変数
   
int type=0;//演算種別格納用
   
int ans;//結果格納変数
   //入力1
   
printf("1つめの値を入力:");
   fgets(buf,63,stdin);
   sscanf(buf,
"%d",&in1);
   
//入力2
   
printf("2つめの値を入力:");
   fgets(buf,63,stdin);
   sscanf(buf,
"%d",&in2);
   
//演算種別入力
   
printf("演算種別を入力(1:+,2:-,3:*,4:/):");
   fgets(buf,63,stdin);
   sscanf(buf,
"%d",&type);
   
//計算処理(加算処理から変更)
   
ans=0;//ansは初期化していないので0を入れておく
   
switch(type){
   
case 1://加算
      
ans=in1+in2;
      
break;
   
case 2://減算
      
ans=in1-in2;
      
break;
   
case 3://乗算
      
ans=in1*in2;
      
break;
   
case 4://除算
      
if(in2){
         ans=in1/in2;
      }
      
else{
         puts(
"0による除算はできません");
      }
      
break;
   
default://それ以外
      
puts("正しく入力されませんでした");
      
break;
   }
   
//出力処理
   
printf("結果:%d\n",ans);
   
//終了待ち
   
puts("Enterキーを押すと終了します。");
   getchar();
   
//終了
   
return 0;

さて、今までは数字で入力していた演算種別入力を文字入力に置き換えるので、
演算種別入力は変更が必要です。

また、その時受け取った値を使用している計算処理の部分も変更が必要になります。

まずは、演算種別入力を変更しますが、 fgets 関数で受け取った文字列の一文字目を使用することにするので、
sscanf 関数の呼び出しを削除します。
<  1>
<  2>
<  3>
<  4>
<  5>
<  6>
<  7>
<  8>
<  9>
< 10>
< 11>
< 12>
< 13>
< 14>
< 15>
< 16>
< 17>
< 18>
< 19>
< 20>
< 21>
< 22>
< 23>
< 24>
< 25>
< 26>
< 27>
< 28>
< 29>
< 30>
< 31>
< 32>
< 33>
< 34>
< 35>
< 36>
< 37>
< 38>
< 39>
< 40>
< 41>
< 42>
< 43>
< 44>
< 45>
< 46>
< 47>
< 48>
< 49>
< 50>
< 51>
< 52>
< 53>
#include <stdio.h>

int main(void)
{
   
//変数宣言/定義
   
char buf[64]="";//空文字列で初期化
   
int in1=0;//入力1格納変数
   
int in2=0;//入力2格納変数
   
int type=0;//演算種別格納用
   
int ans;//結果格納変数
   //入力1
   
printf("1つめの値を入力:");
   fgets(buf,63,stdin);
   sscanf(buf,
"%d",&in1);
   
//入力2
   
printf("2つめの値を入力:");
   fgets(buf,63,stdin);
   sscanf(buf,
"%d",&in2);
   
//演算種別入力
   
printf("演算種別を入力(+:加算,-:減算,*:乗算,/:除算):");
   fgets(buf,63,stdin);
   
//計算処理(加算処理から変更)
   
ans=0;//ansは初期化していないので0を入れておく
   
switch(type){
   
case 1://加算
      
ans=in1+in2;
      
break;
   
case 2://減算
      
ans=in1-in2;
      
break;
   
case 3://乗算
      
ans=in1*in2;
      
break;
   
case 4://除算
      
if(in2){
         ans=in1/in2;
      }
      
else{
         puts(
"0による除算はできません");
      }
      
break;
   
default://それ以外
      
puts("正しく入力されませんでした");
      
break;
   }
   
//出力処理
   
printf("結果:%d\n",ans);
   
//終了待ち
   
puts("Enterキーを押すと終了します。");
   getchar();
   
//終了
   
return 0;

次に、計算処理の case の条件を変更します。
<  1>
<  2>
<  3>
<  4>
<  5>
<  6>
<  7>
<  8>
<  9>
< 10>
< 11>
< 12>
< 13>
< 14>
< 15>
< 16>
< 17>
< 18>
< 19>
< 20>
< 21>
< 22>
< 23>
< 24>
< 25>
< 26>
< 27>
< 28>
< 29>
< 30>
< 31>
< 32>
< 33>
< 34>
< 35>
< 36>
< 37>
< 38>
< 39>
< 40>
< 41>
< 42>
< 43>
< 44>
< 45>
< 46>
< 47>
< 48>
< 49>
< 50>
< 51>
< 52>
#include <stdio.h>

int main(void)
{
   
//変数宣言/定義(1)
   
char buf[64]="";//空文字列で初期化
   
int in1=0;//入力1格納変数
   
int in2=0;//入力2格納変数
   
int ans;//結果格納変数
   //入力1
   
printf("1つめの値を入力:");
   fgets(buf,63,stdin);
   sscanf(buf,
"%d",&in1);
   
//入力2
   
printf("2つめの値を入力:");
   fgets(buf,63,stdin);
   sscanf(buf,
"%d",&in2);
   
//演算種別入力
   
printf("演算種別を入力(+:加算,-:減算,*:乗算,/:除算):");
   fgets(buf,63,stdin);
   
//計算処理(加算処理から変更)
   
ans=0;//ansは初期化していないので0を入れておく
   
switch(buf[0]){//(2)
   
case '+'://(3)加算
      
ans=in1+in2;
      
break;
   
case '-'://減算
      
ans=in1-in2;
      
break;
   
case '*'://乗算
      
ans=in1*in2;
      
break;
   
case '/'://除算
      
if(in2){
         ans=in1/in2;
      }
      
else{
         puts(
"0による除算はできません");
      }
      
break;
   
default://それ以外
      
puts("正しく入力されませんでした");
      
break;
   }
   
//出力処理
   
printf("結果:%d\n",ans);
   
//終了待ち
   
puts("Enterキーを押すと終了します。");
   getchar();
   
//終了
   
return 0;
5行目の(1)、変数の集団定義ですが、変数 type の定義を消去しました。
文字列中の文字を使うようにしたことで、必要なくなってしまったためです。

24行目の(2)は、 switch の指定値として buf の一文字目を与えています。
このコードだと一文字目以外に入れたものは完全無視ということになりますが、
今回の用途ならば、特にこれといって問題はないでしょう。
一文字使うだけなら fgets 関数ではなく getchar 関数でもいいのではないか?と思った方。(↓のコードですね)
buf[0]=getchar();

前にも少し触れましたが、キーボードからの入力は一文字入力しただけに見えても、
Enterキーを入力した時に改行文字 '\n' が入ってしまうので、ちょっと厄介なことになります。
というのも、キーボード入力ストリームは文字が全て読み込まれずに残留した場合、
次の読み出し時に残留したデータが読み込まれることになっています。

厄介なのは、残留したデータが読み込める場合は入力待ちにならないということです。
実際に21行目の fgets 関数を getchar 関数に置換えてみれば分かると思いますが、
最後の終了待ちの getchar 関数で入力待ちにならずに通過します。
この時、 getchar 関数はキーボード入力ストリームに残っていた改行文字か、
直前の入力で二文字以上入力した場合は二文字目を入力として返しています。

fgets 関数でも限界長として渡している63バイト以上を入力すれば同様の現象が起きますが、
今回のプログラムではそれほど長い入力をされることは考慮していません。


25行目(3)他は、 case に '+' 等を投入しています。
switch の回でも書いたとおり、 '+' 等のように '' で文字を囲うと文字コードを表す整数となります。
文字比較を行う時はこの表記を用いたほうが、読みやすくなります。


今回は、修正差分が小さいので意図的なバグ混入は行っていません。
・・・自然に混ぜれなかったと言う方が正しいかな(笑)

さて、いつまでも計算機を御題にしていて飽きられてもいけないので、
次回からは簡単なゲームを作っていこうと思います。

[前へ]   [目次へ]   [次へ]

プログラミング講座 総合目次

最終更新 2008/10/16