No.16913![]() |
変数に式を代入しそのまま計算する方法 投稿者---HirO(2004/09/26 22:23:54) |
||
始めまして、最近になってC言語を始めたHirOと申します。 極めて初歩的なのですが、質問させて下さい。 作りたいプログラムの内容 1.画面に「式を入力して下さい」と表示し、入力待ちになる 2.入力すると、答えを画面に表示する。 それで、自分ながらに作ったソースですが #include <stdio.h> void main() { int siki; printf("式を入力して下さい:"); scanf("%d",&siki); printf("答えは[%d]です",siki); } となりました。 実行して「10+15」と入力しても、 「答えは[10]です」としか表示されません。 int型なので、+以降のことが代入されていないのでしょうか? 本当に初歩的な質問で申し訳ありません。 |
No.16914![]() |
Re:変数に式を代入しそのまま計算する方法 投稿者---Sciggepy(2004/09/26 22:36:22) |
||
>始めまして、最近になってC言語を始めたHirOと申します。 >極めて初歩的なのですが、質問させて下さい。 > >作りたいプログラムの内容 >1.画面に「式を入力して下さい」と表示し、入力待ちになる >2.入力すると、答えを画面に表示する。 作ったことがあるので分かるのですが、これをやるのは、結構大変です。 >実行して「10+15」と入力しても、 >「答えは[10]です」としか表示されません。 scanfは、計算まではしてくれません。この場合、数値として認識できる+以前が変数に格納されるので、10が入ったというわけです。 |
No.16915![]() |
Re:変数に式を代入しそのまま計算する方法 投稿者---HirO(2004/09/27 00:36:13) |
||
>scanfは、計算まではしてくれません。この場合、数値として認識できる+以前が変数に格納されるので、10が入ったというわけです。 ありがとうございました。 式がsiki変数に代入されないのは、変数がint型だからなのでしょうか? それとも、scanfは数字のみを取り扱うことが可能だからなのでしょうか? また、どのようにすればこのプログラムが正常に作動するのか 教えていただけないでしょうか 重ね重ね質問して申し訳ありません。 引き続きお願い致します。 |
No.16918![]() |
Re:変数に式を代入しそのまま計算する方法 投稿者---あかま(2004/09/27 07:54:52) |
||
>式がsiki変数に代入されないのは、変数がint型だからなのでしょうか? >それとも、scanfは数字のみを取り扱うことが可能だからなのでしょうか? scanfは数字でも文字でも文字列でも扱うことができます。 http://www9.plala.or.jp/sgwr-t/c/sec05.html#s5-3 >また、どのようにすればこのプログラムが正常に作動するのか >教えていただけないでしょうか プログラムってのはあまり便利にできてません。 言葉で書けば一言でも、プログラムにすると数行〜数百行などになります。 1.数式を入力する。 2.答えを出力する は 1.数式を入力する 2.数式を分解して演算子、数字に分ける 3.数字同士を演算子通りに計算する 4.その答えを表示する になり、これらの1〜4はさらに細かく分解して、プログラムを書いていくことになります。 電卓系のプログラムは簡単そうで実はむずかしかったりするので、 初心者向けの参考書にのっている問題や、このHPの練習問題から手をつけられるといいと思います。 あえて思いっきり手を抜いて書くとこんな感じです。 これは2つの数字の足し算しかできません。 #include <stdio.h> int main(){ int a,b,ans; scanf("%d+%d",&a,&b);//式の入力と分解。一行と短いがscanfの中でとても複雑なことをしている(1.と2.) ans = a + b;//計算する(3.) printf("=%d\n",ans);//出力する(4.) return 0; } ***入力例*** 12+5 ***出力例*** =17 ************ もし、 ***入力例*** 12-5 などと入力してしまうとどうなるかは試してみてください。 これらをきちんと動作するようにしていくと、段々複雑なプログラムになっていきます。 |
No.16920![]() |
Re:変数に式を代入しそのまま計算する方法 投稿者---Sciggepy(2004/09/27 13:21:11) |
||
即席で作ったので少し怪しい部分がありますが、下のサンプルでは、四則カッコつき計算ができます。 #include <cstdio> #include <cstdlib> #include <string> #include <stack> using namespace std; #define ORDER(o) (((o)=='+'||(o)=='-')?1:(((o)=='*'||(o)=='/')?2:0)) bool calc(const char *fml,double *ret) { stack<char> opr; stack<double> num; string tmp; while(1) { for(tmp="";*fml&&*fml!='+'&&*fml!='-'&&*fml!='*'&&*fml!='/'&& *fml!='('&&*fml!=')';fml++) tmp+=*fml; if(*fml!='(') num.push(atof(tmp.c_str())); else { fml++; int bc; for(tmp="",bc=1;*fml&&bc;fml++) { if(*fml=='(') bc++; else if(*fml==')') bc--; tmp+=*fml; } unsigned len=tmp.length(); if(bc||!len) return false; tmp.replace(len-1,1,1,'\0'); double d; if(!calc(tmp.c_str(),&d)) return false; num.push(d); } char op; while(opr.size()&&ORDER(*fml)<ORDER(op=opr.top())) { opr.pop(); if(num.size()<2) return false; double d1=num.top(); num.pop(); double d2=num.top(); num.pop(); switch(op) { case '+': num.push(d2+d1); break; case '-': num.push(d2-d1); break; case '*': num.push(d2*d1); break; case '/': if(d1) num.push(d2/d1); else return false; break; } } if(!*fml) { if(num.size()!=1) return false; *ret=num.top(); return true; } else opr.push(*fml); fml++; } } int main() { char f[64]; double d; scanf("%s",f); if(calc(f,&d)) printf("%f",d); return 0; }演算子と数値をそれぞれスタックに積んで、優先順位の低いものが現れたら、降ろして計算するというものです。 Cだと面倒な部分があるので、C++で書いてみました。 以前質問に出したもの《リンク》は、Cで書いてあります。(速度重視のため、かなり煩雑になっています。) |
No.16922![]() |
Re:変数に式を代入しそのまま計算する方法 投稿者---かずま(2004/09/27 17:53:51) |
||
> 即席で作ったので少し怪しい部分がありますが、下のサンプルでは、 > 四則カッコつき計算ができます。 怪しい部分というと、次のような間違った入力に対して、計算結果を出して しまうことでしょうか? *12-34 12-*34 12*-34 12(34) 12+abc abc+34この掲示板の過去ログ No.840 の下のほうに 30行で書いた Cプログラムが あります。 |
No.16928![]() |
Re:変数に式を代入しそのまま計算する方法 投稿者---Sciggepy(2004/09/27 23:01:19) |
||
>怪しい部分というと、次のような間違った入力に対して、計算結果を出して >しまうことでしょうか? > *12-34 12-*34 12*-34 12(34) 12+abc abc+34-5+6とか3*(1+2)-4も無理でしょう。 #またまた失敗作です(~~;)/ ̄L #自分もここで勉強させて頂いているつもりなので、お許し下さい。 |
No.16930![]() |
Re:変数に式を代入しそのまま計算する方法 投稿者---HirO(2004/09/28 00:01:28) |
||
Sciggepyさん、あかまさん、かずまさん、 大変参考になりました。ありがとうございます。 意外と複雑になるんですね・・・ もっと勉強を重ねてみます。 これからも何かつまづいたことがあったら、 また伺うかもしれません。そのときはよろしくお願いします。 |