• 締切済み

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ケタ以内というのは小数点以下の桁数も入れて、という意図です。 上のソースでは変換演算子に桁数を指定していませんが・・・。

すると、全ての回答が全文表示されます。

専門家に質問してみよう