• 締切済み

scanf関数のプログラムをgetchar関数で

scanf関数を使って四則演算、論理輪、論理積をint、float、double型で表示するプログラムを作ったのですが これをscanf関数ではなく、getchar関数で組みなおし、関数化する課題が出ました。 そのままscanf関数のところだけを変えても型が違うというエラーが出てうまくいきません。 どうすればいいでしょうか? 一応scanf関数で組んだプログラムの一部を載せておきます。 #include <stdio.h> #include <math.h> main() { float a , b; float x[5]; printf("正の数字を2つ入力して下さい(小数点を含めて4ケタまで):\n"); for(;;) { printf("\na="); scanf("%f" , &a); if(a>=0 && a<=9999 && a) { break; } else { printf("****aに入力エラー****\n"); printf("数字は4ケタ以内の正数を入力:\n"); continue; } } for(;;) { printf("b="); scanf("%f" , &b); if(b>=0 && b<=9999 && b) { break; } else { printf("****bに入力エラー****\n"); printf("数字は4ケタ以内の正数を入力:\n"); continue; } } x[0] = a+b; x[1] = a-b; x[2] = a*b; x[3] = a/b; x[4] = a||b; x[5] = a&&b; printf("\n"); printf("int型 結果:\n足し算=%d\n" , (int)x[0]); printf("引き算=%d\n" , (int)x[1]); printf("掛け算=%d\n" , (int)x[2]); printf("割り算=%d\n" , (int)x[3]); printf("論理和=%d\n" , (int)x[4]); printf("論理積=%d\n" , (int)x[5]); printf("\n"); printf("float型 結果:\n足し算=%f\n" , x[0]); printf("引き算=%f\n" , x[1]); printf("掛け算=%f\n" , x[2]); printf("割り算=%f\n" , x[3]); printf("論理和=%f\n" , x[4]); printf("論理積=%f\n" , x[5]); ・ ・ ・ getchar(); }

みんなの回答

  • Interest
  • ベストアンサー率31% (207/659)
回答No.4

> ただ、0.1と0.2のように小数の場合どのような結果になるのか >(自分のプログラムの結果が正しいかどうか)を理解していませんでした。 『問題の前提条件が成りたっていないので計算結果に意味がない』と書いたつもりだったのですが理解していただいたでしょうか? (プログラムの勉強ということで、計算機内部で浮動小数点がどのように表現されるか知っておこう、という意味で捉えても、小数同士の論理和、論理積をとることに合理性を感じません。) > さきほどコーディング規約というものを確認したところ、 > 入力する数値は-999.999~+999.999にせよとの事でしたので小数は含みます。 そうですか。( printf("数字は4ケタ以内の正数を入力:\n"); はすでに間違っていたわけですね。) では、atof という関数を使いましょう。math.h, stdlib.h をインクルードすれば使えます。 【 atof 】文字列を浮動小数点に変換する。 書式: double atof(const char *s); 文字列の先頭に空白が入っていると、その空白は無視されます。 入力文字列に数字が入っていない場合の処理は未定義(処理系依存)です。 (atofの使い方例) const char *s = " -123.45"; double d; d = atof(s); printf("s=%s, d=%5.2lf\n", s, d); (実行結果) s= -123.45, d=-123.45 キー入力から文字列をもらってくるところは、scanfがダメなら char buffer[9]; int i, ch; // キー入力から 1 行読み込む for( i = 0; (i < 8) && ((ch = getchar()) != EOF) && (ch != '\n'); i++ ) buffer[i] = ch; buffer[i] = '\0'; // 文字列の終端に NULL 文字を格納 とすればOK。(入力上限8文字の例です。) コーディング規約、ときくと、関数名や変数名の付け方、引数や戻り値の与え方、コメント文の書き方、っていうイメージがあるんですけどねぇ・・・

nation77
質問者

お礼

回答ありがとうございます。 >『問題の前提条件が成りたっていないので計算結果に意味がない』と書いたつもりだったのですが理解していただいたでしょうか? >(プログラムの勉強ということで、計算機内部で浮動小数点がどのように表現されるか知っておこう、という意味で捉えても、小数同士の論理和、論理積をとることに合理性を感じません。) 仰りたいことは分かりますが、私自身で作った問題ではなく課題として出されているので真意は分かりかねます。

  • Interest
  • ベストアンサー率31% (207/659)
回答No.3

> 0.1と0.2の論理積はこのプログラムでは 1 となりますが、 > 正しくなく、正解は 0 ということでしょうか? 論理演算というのは、ご存知のとおり  真 かつ 真 ならば 真 のように、真(1)か偽(0)しか相手にしていません。ビット列は、ただこの0と1が列になっているだけのことです。0.1は真でしょうか、偽でしょうか? もうここで議論の前提条件が崩れてしまっています。計算結果が正しいかどうか以前に、問題設定が間違っているのです。 > ただプログラムが正しく動くということにしか 「正しく動く」とはどいうことなのか考え直してみましょう。 設計者の狙い通りに動くことを「正しく動く」と定義するなら、どのような入力に対してどのような出力を期待するか、はっきりしていなければ正しく動いているかどうか確認できません。 もう一度、 ○ 入力する値は小数を含んでよいのか ○ 入力にして期待する出力はどうなるか を確認してみてください。 その上で「入力は小数を含む」ということでしたら、文字列から数字(数値)を引っ張り出す方法を紹介します。

nation77
質問者

補足

返信ありがとうございます。 >論理演算というのは、ご存知のとおり > 真 かつ 真 ならば 真 >のように、真(1)か偽(0)しか相手にしていません。 例のように1と1のときは真(1)、0と1のときは偽(0)のような論理演算は理解できました。 ただ、0.1と0.2のように小数の場合どのような結果になるのか(自分のプログラムの結果が正しいかどうか)を理解していませんでした。 >その上で「入力は小数を含む」ということでしたら、文字列から数字(数値)を引っ張り出す方法を紹介します。 さきほどコーディング規約というものを確認したところ、 入力する数値は-999.999~+999.999にせよとの事でしたので小数は含みます。 よろしければ、上記の数値を引っ張り出す方法のご紹介をお願いします。

  • Interest
  • ベストアンサー率31% (207/659)
回答No.2

ANo.1 = Interest です。 > 4ケタ以内というのは小数点以下の桁数も入れて、という意図です。 では、実数同士の論理積や論理和はどう扱うつもりなのですか? 例えば、0.1と0.2の論理積の正しい出力はいくつになると考えますか? 確かに浮動小数点は計算機内部でIEEE754形式で0と1の列になっていますが、それらの論理積や論理和をとることに計算としての意味はありませんよね。(計算自体は可能ですが。)なので、前提条件が「整数」しか扱わないのではないかと思ったわけです。

nation77
質問者

お礼

>では、実数同士の論理積や論理和はどう扱うつもりなのですか? >例えば、0.1と0.2の論理積の正しい出力はいくつになると考えますか? ただプログラムが正しく動くということにしか頭がいってなかったのでそこまで考えていませんでした。 0.1と0.2の論理積はこのプログラムでは 1 となりますが、正しくなく、正解は 0 ということでしょうか?

  • Interest
  • ベストアンサー率31% (207/659)
回答No.1

なんじゃこりゃ? と、ソースコードを見て驚いてしまいました。 入力する値の範囲は 0~9999 という意図は感じましたが、小数点を入力してもいいのでしょうか? 例えば、0.1と0.2を入力するとか。 (入力待ちのループの拙さはさておき)0.1と0.2を入力した場合、論理和、論理積はどのようになると期待していますか? コンピュータ内部では浮動小数点も2進表現になるので、計算できることはできますが・・・ > printf("数字は4ケタ以内の正数を入力:\n"); と書いてあるので、実は「整数」しか扱わないとか?? scanf を getchar に置き換える前に、入力する値の範囲(整数なのか実数なのか)をはっきりさせましょう。それによって置き換え方が変わってきます。

nation77
質問者

お礼

プログラミングをはじめたばかりですので、かなり不可解なソースになっているかと思います、スイマセン。 小数点の入力も含みます。 意味が違うんですが、4ケタ以内というのは小数点以下の桁数も入れて、という意図です。 上のソースでは変換演算子に桁数を指定していませんが・・・。

関連するQ&A

  • 長方形、円、三角形の計算するプログラムでエラーがでます

    タイトルの通りなんですがエラーがでます>< コンパイラはできたのですが、実行して二つ目の入力するとこで、入力したあと止まります。 どこがおかしいのでしょうか? #include <stdio.h> int sikaku(void); int en(void); int main(void) { char ch; int a,b; printf("円(A) 長方形(B) 三角形(C)\n"); printf("入力してください:"); ch = getche(); if(ch == 'C'){ printf("\n底辺を入力してください:"); scanf("%d ",a); printf("高さを入力してください:\n"); scanf("%d",b); printf("%dです",a * b); } else if(ch == 'B') sikaku(); else if(ch == 'A') en(); return 0; } int en(void) { int a; float f; printf("\n半径を入力してください:"); scanf("%d",a); printf("円周率を入力してください:"); scanf("%f",f); printf("%fです",a * a * f); return 0; } int sikaku(void) { int a,b; printf("\n縦を入力してください:"); scanf("%d",a); printf("横を入力してくさい:\n"); scanf("%d",b); printf("dです",a * b); return 0; }

  • C言語 プログラミングで行詰まりました…

    標準入力(キーボード)からi,jk,nの値を入力し、次の漸化式を計算し、X_0からX_nまで求めるプログラムを作成したいのですが、うまく表示されません。どかがおかしいのかご指摘お願いします。 <漸化式> X_n=(a+b)/X_(n-1) , X_0=c(n=0) ================================================================== #include<stdio.h> float f_X(int a,int b,float c) { float y; y=(a+b)/c; return y; } int main (void) { int number,i,j; float k,l,n,X; printf("i:"); scanf("%d", &i); printf("j:"); scanf("%d", &j); printf("k:"); scanf("%f", &k); printf("n:"); scanf("%f", &n); X=k; printf("X_0= %.6f\n",X); for(number=1;number<=n;number++) { l=f_X(i,j,X); printf("X_%d= %.6f \n",number,l); X=l; } return 0; } ===================================================================

  • scanf()関数の使い方について

    はじめまして。 質問があります。 まずは、以下のコードを見てください。 ---------------------------------------------------------------- #include<stdio.h> int main(void) { char c; int i; printf("0を入力すると終了します。\n"); while(1) { printf("文字を入力してください=>"); scanf("%c",&c); printf("入力した文字は %c です。\n",c); printf("数字を入力してください=>"); scanf("%d",&i); if(i==0) { break; } printf("入力した数字は %d です。\n",i); } return 0; } ---------------------------------------------------------------- 上のコードを実行すると、初回はscanf()はcharとintの両方とも 入力待ちになってくれるのですが、2回目以降はcharは入力待ちに なってくれません。これは、なぜなのでしょうか? ご教授お願いします。 現在VC++6.0を使用しております。

  • プログラムがうまくいきません。教えてください。

    プログラムがうまくいきません。教えてください。 #include <stdio.h> int main(void){ int a, b, c, d, f; printf("国語="); scanf("%d", &a); printf("算数="); scanf("%d", &b); printf("理科="); scanf("%d", &c); printf("社会="); scanf("%d", &d); f = ((a>90)?1:0)+((b>90)?1:0)+((c>90)?1:0)+((d>90)?1:0); printf("\n合計[%d],平均[%.2f]\n",(a+b+c+d),((double)(a+b+c+d)/4.0)); printf("国語[%d],[%.3f%%],[%d]\n",a,((double)a/1.5),((a>90)?1:0)); printf("算数[%d],[%.3f%%],[%d]\n",b,((double)b/1.5),((b>90)?1:0)); printf("理科[%d],[%.3f%%],[%d]\n",c,((double)c/1.5),((c>90)?1:0)); printf("社会[%d],[%.3f%%],[%d]\n",d,((double)d/1.5),((d>90)?1:0)); printf("総合判定[%d],\n", ((f>=3)?1:0)); return (0); } と入力したのですが、実行結果の国語から社会までの[]部分を上下揃えたいのですが揃いません。このプログラムにどのようなことを追加すれば揃えることができますか?教えてください!

  • scanf関数の戻り値について

    --------------------------------------- #include<stdio.h> int main(void) { int dt; while(scanf("%d",&dt)==1){ if(dt==0){ printf("0は入力しないでください\n"); puts(""); } else if(dt<0){ dt=-dt; printf("入力値の絶対値は「%d」です\n",dt); puts(""); } else{ printf("入力値の絶対値は「%d」です\n",dt); puts(""); } } return 0; } --------------------------------------- 以上のプログラムについて疑問があります。 scanf関数の戻り値が1の間、繰り返すというもので、入力の時に整数入力ですが、あえて実数である1.1を入れたとします。 scanfの戻り値は1で、dtには整数部の1だけ設定されていたので、これでもうまくいくのかと思ったのですが、次の入力はscanfの戻り値が0になっていて出来ませんでした。 何故0になっているのかわかりません。 入力バッファに何か残ってしまっているということなのでしょうか? 以上教えていただけると嬉しいです。

  • getchar()について 教えてください。

    visual studio 2010 professinalで以下のソースをデバッグして ”続行するには何かキーを押してください!”  で待機させたいのですが getchar()一個だけでは実現しません。   2個重ねるとOKです。どうしてでしょうか。  -------------- 以下のようにscanf関数がなければokということは突き止めたのですが、、、。  ご教授ください。 #include <stdio.h> int main(void) { int i; printf("なにか数字を入力してください。\n"); scanf("%d",&i); printf("今あなたが入力した数字は%dです。\n",i); printf("続行するには何かキーを押してください!"); getchar(); //getchar(); return 0; } ---------------------------------------------------------------- int main(void) { printf("続行するには何かキーを押してください!"); getchar();   return 0; }

  • 関数の値(scanf)

    初心者なもので、言葉の使い方を間違っていたら申し訳ありません。いいたいことが伝わればよいのですが…。 scanfに関して疑問に思ったことがあります。経験的なことなので、正しいかわからないです。次の(1)と(2)から(3)のことが正しいか教えてください。 (1) int a; do{ printf("整数を入力してください\n"); }while(scanf("%d",&a) ==0); printf("入力した数は、%dです",a) このとき、「(いかなる整数)+(ENTER)」を入力しても、do~whileのループを抜け出す。 (2)また、上のプログラムで、継続条件式の中身を  … }while(scanf("%d",&a)!=0);  … とすると、「(いかなる整数)+(ENTER)」を入力してもループが抜け出せない。 (3)したがって(1)と(2)から、scanf()は入力するだけで、値を真(1)を返す。

  • 因数分解プログラム(C言語)について(1)

    ”因数分解を行うプログラムについて”の質問と同じ者です。 みなさんのご回答を参考にして、作ってみたのですが、 ポインタとかの使い方などがわからず、実行すると、 不正な処理を行ったので終了しますとなってしまいます。 どなたか、具体的にどこが悪いのか、 そしてどのように直せば正しく実行されるのか、 教えて下さい。お願いします。 以下↓がプログラムです。 800文字以上のため二つに分割しました。 #include <stdio.h> #include <math.h> #include <process.h> /*関数プロトタイプ宣言*/ int input(int *,int *,int *); int judge(int *,int *,int *); int bunkai1(int *,int *,int *,int *,int *,float *); int bunkai2(int *,int *,int *,int *,int *,float *); int yakubun1(int *,int *,int *,int *,int *,int *,int *); int yakubun2(int *,int *,int *,int *,int *,int *,int *); int output(int *,int *,int *,int *); /*関数の呼び出し*/ int main(void) { int a,b,c,q,n1,m1,min1,flag,i,d,e,m2,n2,min2,f,g; float D; input(&a,&b,&c); judge(&a,&b,&c); bunkai1(&a,&b,&q,&n1,&m1,&D); bunkai2(&a,&b,&q,&n2,&m2,&D); yakubun1(&m1,&n1,&min1,&flag,&i,&d,&e); yakubun2(&m2,&n2,&min2,&flag,&i,&f,&g); output(&d,&e,&f,&g); return (0); } /*数値入力関数*/ int input(int *a,int *b,int *c) { printf("a*x^2+b*x+c=0で,a,b,cを入力して下さい。\n"); printf("a="); scanf("%d",a); printf("b="); scanf("%d",b); printf("c="); scanf("%d",c); if(*a == 0){ printf("a = 0なので因数分解できません。\n"); exit(1); } return 0; } つづく

  • 行列の積を関数を使って求める・・?

    2つの行列の行と列を入力し、積を計算するプログラムを関数を使って書きたいのですが、上手く行きません。どこをどのように直したらよいか教えてください!お願いします!! 以下が私が書いたプログラムです。 #include<stdio.h> #define NUMBER 10 int first(int x1,int x2,int y1,int y2,int i,int j,int k) { int a[NUMBER][NUMBER] = {0}; int b[NUMBER][NUMBER] = {0}; int c[NUMBER][NUMBER] = {0}; do{ printf("2つの行列の行と列を入力してください\n"); scanf("%d", &x1); scanf("%d", &x2); scanf("%d", &y1); scanf("%d", &y2); if(x1 != y2){ printf("行列の積は計算できません\n"); } }while(x1 != y2); printf("行列Aの要素を入力してください\n"); for(i=0; i<x1; i++){ for(j=0; j<x2; j++) scanf("%d", &a[i][j]); } printf("行列Bの要素を入力してください\n"); for(j=0; j<y1; j++){ for(k=0; k<y2; k++) scanf("%d", &b[j][k]); } } int second(int x1,int x2,int y1,int y2,int i,int j,int k) { int a[NUMBER][NUMBER] = {0}; int b[NUMBER][NUMBER] = {0}; int c[NUMBER][NUMBER] = {0}; for(i=0; i<x1; i++){ for(k=0; k<y2; k++){ for(j=0; j<x2; j++) c[i][k] = c[i][k] + a[i][j]*b[j][k]; } } for(i=0; i<x2; i++){ for(k=0; k<y2; k++) printf("%3d", c[i][k]); printf("\n"); } } int main(void) { int a[NUMBER][NUMBER] = {0}; int b[NUMBER][NUMBER] = {0}; int c[NUMBER][NUMBER] = {0}; printf("行列の積を計算します\n %d\n", first(x1,x2,y1,y2,i,j,k)); printf("行列Aと行Bの積は\n %3d",second(x1,x2,y1,y2,i,j,k)); }

  • プログラムに詳しい方教えてください!

    #include<stdio.h> void fxl(int x,int y); int main(void) { int a,b,m,n; printf("整数aの値を入力\n"); scanf("%d",&b); printf("整数bの値を入力\n"); scanf("%d",&b); m=a; n=b; fxl(m,n); printf("a=%dとb=%dを加算した値は%d\n",ab,m); printf("a=%dからb=%dを減算した値は%d\n",ab,n); return 0; } void fxl(int x,int y) { int j,k; j=x; k=y; x=j+k; y=j-k; } このプログラムを作ってみたのはいいのですが、参照渡しを使って正常に足し算、引き算をするにはどうすればよいのでしょうか。