下記の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;
}
A 回答 (5件)
- 最新から表示
- 回答順に表示
No.5
- 回答日時:
手元の WSL では g++ 6.3.0 でも想定した通りの動作になっているから, おそらく「とてつもなく古い g++」でない限りは「プログラムとしての問題」はないと思うよ.
どこかのタイミングで failbit が立ってたりしないかなぁ. 「入力ストリームが最初の位置に戻される」ということではないはずだけど, あなたのいう症状が手元では全く出てこないので完全に推測の域を出ない.
No.4
- 回答日時:
確認だけど, このプログラムだと「3.14x」とか「3.14y」とかを 1回入力したらプログラムそのものも終了するよね. それを前提に
・まずこのプログラムを実行し, そこで「3.14y」と入力すると
val = 3.39
ch = y
と出力されてプログラムが終了する
・その次に改めてこのプログラムを実行し, そこで「3.14x」と入力すると
val = 0.25
ch = 3
と出力されてプログラムが終了する
という動作になっていて困っている, ということでいい?
No.3
- 回答日時:
回答になっていませんが、逆の順番にやってみたらどうなります?
つまり、
標準入力から、3.14xと入力すると、
val = 3.39
ch = x
の期待通りの結果になるのですが、
3.14yと入力すると、
val = 0.25
ch = 3
の結果になってしまいます
ということはないでしょうか?
No.1
- 回答日時:
人工知能はこう答えたけど、私はプログラミングのことはわかりません。
-----------
このコードでは、最初に入力された文字を 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 型に変換する方法があります。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C++のcase文の書き方 4 2023/02/24 20:50
- C言語・C++・C# C++初心者です stirng 2 2022/09/20 20:43
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# カードシャッフルのブログラムを使ってc言語でブラックジャックをしたい 2 2022/04/12 15:13
- Visual Basic(VBA) Vbaで数式をポーランド記法に変換するコードを作って実行しようとするとフリーズします。 1 2022/05/24 17:53
- C言語・C++・C# C++プログラミングコードにポリモーフィズムを取り入れ方を教えてください。 2 2023/06/09 11:17
- Visual Basic(VBA) vbaでセルに入力したときに,その横にあるセルを保護し入力不可にするマクロを作りたいです。 2 2022/04/24 20:59
- Visual Basic(VBA) select caseの入れ子 3 2023/03/08 18:48
- TOEFL・TOEIC・英語検定 This has not yet been proven to be the case for an 2 2022/06/20 13:56
- JavaScript jsで、switch文で書かれた分をif文にできませんか。 1 2022/07/28 15:10
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・【大喜利】【投稿~11/22】このサンタクロースは偽物だと気付いた理由とは?
- ・お風呂の温度、何℃にしてますか?
- ・とっておきの「まかない飯」を教えて下さい!
- ・2024年のうちにやっておきたいこと、ここで宣言しませんか?
- ・いけず言葉しりとり
- ・土曜の昼、学校帰りの昼メシの思い出
- ・忘れられない激○○料理
- ・あなたにとってのゴールデンタイムはいつですか?
- ・とっておきの「夜食」教えて下さい
- ・これまでで一番「情けなかったとき」はいつですか?
- ・プリン+醤油=ウニみたいな組み合わせメニューを教えて!
- ・タイムマシーンがあったら、過去と未来どちらに行く?
- ・遅刻の「言い訳」選手権
- ・好きな和訳タイトルを教えてください
- ・うちのカレーにはこれが入ってる!って食材ありますか?
- ・おすすめのモーニング・朝食メニューを教えて!
- ・「覚え間違い」を教えてください!
- ・とっておきの手土産を教えて
- ・「平成」を感じるもの
- ・秘密基地、どこに作った?
- ・【お題】NEW演歌
- ・カンパ〜イ!←最初の1杯目、なに頼む?
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
プログラミング初心者です。 Py...
-
正負を反転させて出力するプロ...
-
C言語について質問です。 0以下...
-
*をユーザーが入力した数字の数...
-
Excel VBAで、Application.Inpu...
-
scanfが2回使えない・・・?;
-
数字以外が入力されたらエラー...
-
VB.NETで16進数+16進数や16進...
-
cout関数を使っているのですが...
-
getchar()について 教えてくだ...
-
batプログラム上で文字列を入力...
-
コンソールアプリの入力時に改...
-
コンボボックスで日本語入力を...
-
C++のcinの動作
-
C言語scanf_sで何故か2回入力に...
-
プログラムの進行が一時ストッ...
-
C言語初心者です。ファイルの読...
-
プログラミングC言語について
-
漢字のソートについて
-
C言語 逆ピラミッドの作り方
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
プログラミング初心者です。 Py...
-
正負を反転させて出力するプロ...
-
*をユーザーが入力した数字の数...
-
数字以外が入力されたらエラー...
-
Eclipseコンソール表示を、リセ...
-
scanfが2回使えない・・・?;
-
java初心者です。入力されたの...
-
Excel VBAで、Application.Inpu...
-
ワードで文字を入力する時の変...
-
WindowsでEOF
-
batプログラム上で文字列を入力...
-
getchar()について 教えてくだ...
-
cout関数を使っているのですが...
-
コマンドプロンプトからのEOFの...
-
"scanf"でエンターで改行させな...
-
VisualStudio2019のコードアナ...
-
C言語scanf_sで何故か2回入力に...
-
至急教えてください!プログラ...
-
scanf が無視されます
-
EDITコントロールで入力できる...
おすすめ情報
g++は、12.0.0
clang++は、12.0.0
で行っています。
結果は、上に書いた通りです。
そうです。
順番は関係ないです。
最後の文字が何であるかだけでの再現性です。(うまくいくものはうまくいくし、うまくいかないものはうまくいかない。)
ちなみに、3.14の後にリターンを押して、それから文字を入れる場合はOKです。
また、doubleをintに変えてやった場合は、文字を続けて入れた場合、リターンして入れた場合、両方ともOKになります。
こちらでも確認してみたのですが、
WindowsとLinuxの環境でのg++では共に、OKみたいです。
ただ、macはiMacとMacBook Pro共に上に書いたような状態になります。
ちなみにiMacのg++のヴァージョンは、13.0.0です。
macの環境でもうまくいってる人っています?
何か私のmacの環境でおかしなところがあるのかもしれないので^^;
後、macでは、
g++は実際には、clang++が動いているみたいです。
g++とclang++の差かもしれません。