アプリ版:「スタンプのみでお礼する」機能のリリースについて

下記のc++のcinの動作について質問があります。分かる方、教えてください。
コンパイルして実行後、標準入力から、3.14yと入力すると、
val = 3.39
ch = y
の期待通りの結果になるのですが、
3.14xと入力すると、
val = 0.25
ch = 3
の結果になってしまいます。
調べて見ると、最後に入れる数値以外の文字(この場合の、xやy)が、文字によってdoubleと認識されて取り込まれる場合があるようで、その場合取り込まれた文字がdoubleに変換されて0になって、入力ストリームが最初の位置に戻されるようなのですが、これは正しい動作なのでしょうか?それとも書き方に何かまずい箇所とかあるのでしょうか?


#include <iostream>
using namespace std;

int main() {

char ch;
cin >> ch;

switch (ch) {
case '.':
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
{
//cout << "here" << endl;
cin.putback(ch);
double val;
cin >> val;
val += 0.25;
cout << "val = " << val << endl;
}
default:
cin >> ch;
cout << "ch = " << ch << endl;
}

return 0;
}

質問者からの補足コメント

  • g++は、12.0.0
    clang++は、12.0.0
    で行っています。
    結果は、上に書いた通りです。

    No.2の回答に寄せられた補足コメントです。 補足日時:2023/02/26 02:29
  • そうです。

    No.4の回答に寄せられた補足コメントです。 補足日時:2023/02/26 09:55
  • 順番は関係ないです。
    最後の文字が何であるかだけでの再現性です。(うまくいくものはうまくいくし、うまくいかないものはうまくいかない。)
    ちなみに、3.14の後にリターンを押して、それから文字を入れる場合はOKです。
    また、doubleをintに変えてやった場合は、文字を続けて入れた場合、リターンして入れた場合、両方ともOKになります。

    No.3の回答に寄せられた補足コメントです。 補足日時:2023/02/26 10:03
  • こちらでも確認してみたのですが、
    WindowsとLinuxの環境でのg++では共に、OKみたいです。
    ただ、macはiMacとMacBook Pro共に上に書いたような状態になります。
    ちなみにiMacのg++のヴァージョンは、13.0.0です。
    macの環境でもうまくいってる人っています?
    何か私のmacの環境でおかしなところがあるのかもしれないので^^;

    No.5の回答に寄せられた補足コメントです。 補足日時:2023/02/26 22:37
  • 後、macでは、
    g++は実際には、clang++が動いているみたいです。
    g++とclang++の差かもしれません。

      補足日時:2023/02/26 23:01

A 回答 (5件)

手元の WSL では g++ 6.3.0 でも想定した通りの動作になっているから, おそらく「とてつもなく古い g++」でない限りは「プログラムとしての問題」はないと思うよ.



どこかのタイミングで failbit が立ってたりしないかなぁ. 「入力ストリームが最初の位置に戻される」ということではないはずだけど, あなたのいう症状が手元では全く出てこないので完全に推測の域を出ない.
この回答への補足あり
    • good
    • 0

確認だけど, このプログラムだと「3.14x」とか「3.14y」とかを 1回入力したらプログラムそのものも終了するよね. それを前提に


・まずこのプログラムを実行し, そこで「3.14y」と入力すると
val = 3.39
ch = y
と出力されてプログラムが終了する
・その次に改めてこのプログラムを実行し, そこで「3.14x」と入力すると
val = 0.25
ch = 3
と出力されてプログラムが終了する
という動作になっていて困っている, ということでいい?
この回答への補足あり
    • good
    • 0

回答になっていませんが、逆の順番にやってみたらどうなります?


つまり、

標準入力から、3.14xと入力すると、
val = 3.39
ch = x
の期待通りの結果になるのですが、
3.14yと入力すると、
val = 0.25
ch = 3
の結果になってしまいます

ということはないでしょうか?
この回答への補足あり
    • good
    • 0

私のところの g++ 12.2.0 では 3.14x でも 3.14y でも


val = 3.39
って表示されてるよ.
この回答への補足あり
    • good
    • 0

人工知能はこう答えたけど、私はプログラミングのことはわかりません。



-----------

このコードでは、最初に入力された文字を ch として読み込み、その文字が '.' もしくは数字の場合に限り、次に double 型の変数 val を読み込んでいます。この val に対して 0.25 を加算し、その結果を出力しています。それ以外の場合には、もう一度文字を読み込んで ch に格納し、その結果を出力しています。

「3.14y」という入力に対しては、最初に '3' が ch に格納され、その後 cin.putback(ch) を使って '3' を入力ストリームに戻しています。次に cin >> val が実行され、3.14 が val に格納されます。最後に ch には 'y' が読み込まれ、それが出力されます。

一方、「3.14x」という入力に対しては、最初に '3' が ch に格納されますが、次に '.' が読み込まれるので、cin.putback(ch) を使って '3' を入力ストリームに戻すことはできません。そのため、cin >> val が実行されると、val には 0.14 が格納されます。その後、'x' が ch に読み込まれ、それが出力されます。

つまり、このコードでは最初に入力された文字が数字や '.' である場合に限り double 型の変数に変換し、それ以外の場合は単に文字として読み込んでいるため、入力によっては意図しない結果になる可能性があります。

もし double 型の数値を正確に読み込む必要がある場合には、より厳密な入力処理を行う必要があります。例えば、std::getline を使って一行を読み込み、それを std::istringstream に渡して double 型に変換する方法があります。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!