質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
86.12%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

解決済

C++ 標準入力でcinの後にgetlineを行うと期待する出力が1行少なくなる

mjk
mjk

総合スコア301

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

2回答

0グッド

0クリップ

332閲覧

投稿2022/11/29 14:21

編集2022/12/01 06:31

参考情報追記

(BA後に見つけた情報です)
cinとgetlineの併用

cinを使用した後にgetlineを仕様すると、getlineで取得した文字列には何も入っていないということが発生します。
引用テキストその原因は、cinは改行文字の前で入力が終わっているため、現在位置から改行までを読み込むgetlineを使用すると、空の文字列になってしまうからです。
引用テキスト併用したい場合には、以下のようにします。

C++

1int n; 2std::string s; 3 4std::cin >> n; 5std::cin.ignore(); // 次の改行文字まで最大1文字読み捨てる 6 7std::getline(std::cin, s);

質問

標準入力でcinの後にgetlineを行うと期待する出力が1行少なくなってしまいます
正しい方法ではないと思うのですがgetlineを1回余分に行うことで期待する出力は得られました。
getlineを1回余分に行わなくても期待する出力を得る為の方法があれば教えていただきたいです。

実現したいこと

C++

1#include <bits/stdc++.h> 2using namespace std; 3 4int main() { 5 int N; 6 cin >> N; 7 8 for (int i = 0; i < N; i++) { 9 string s; 10 getline(cin, s); 11 cout << s << '\n'; 12 } 13}

input

13 2a b c 3d e f 4x y z 5

output

1//現状の出力 2a b c 3d e f

試したこと

C++

1#include <bits/stdc++.h> 2using namespace std; 3 4int main() { 5 int N; 6 cin >> N; 7 8 //↓この処理をしないと次のforループが1回少ないのは何故? 9 string tmp; 10 getline(cin, tmp); 11 12 for (int i = 0; i < N; i++) { 13 string s; 14 getline(cin, s); 15 cout << s << '\n'; 16 } 17}

output

1//期待する出力 2a b c 3d e f 4x y z

補足情報(FW/ツールのバージョンなど)

Ubuntu 20.04 LTS
WSL2
VSCode 1.73.1
Windows10 19044
C++関連
c++17
g++ (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
gdb

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

回答2

1

ベストアンサー

//現状の出力 a b c d e f

本当にそうですか? 実際のところは

//現状の出力 a b c d e f

だったりしないでしょうか?

cin>>N;で何が起こるかというと、標準入力から順次データを読んでいくわけですが
まず先頭に空白や改行等区切り文字があれば読み飛ばし、
数値があったら順次読んでいって、
数値じゃない文字に出会ったら数値はその前の文字までで終わりなので、文字並びを数値に変換して格納し
数値じゃない文字は標準入力に戻します
なので、
3(改行) という入力に対して cin>>N;とした後は、Nに数値が取り込まれ、標準入力の先頭には改行が居ることになります。

その状態でgetline()したならば、いきなり改行があるので1行分のデータ入力が終わりになります。

getlineを1回余分に行わなくても期待する出力を得る為の方法

入力時に、3の後改行でなく

3 a b c d e f g h i

と入力するのが1案。

getline()を余計にやるのでさえなければいいなら、
char c; //ダミー変数
cin >> c;
cin.get();
として改行を読み取ってしまうのがもう一案。

投稿2022/11/29 14:44

編集2022/11/29 15:50
thkana

総合スコア7323

mjk👍を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

mjk

2022/11/29 15:16 編集

>>本当にそうですか? 実際のところは 確かに1行目に空行が出てるようです。 最初にNを出力させておいて空行が出ることが確認できました。 見た感じだと区別がつかないのではっきりとはわからなかったのですが、 ループが1回足りないと思いこんでいました。
thkana

2022/11/29 15:22

あぁ、ちょっと勘違いしてました。C++のstreamあんまり使わないもので。 cin.get()で一文字読み込みなので、こいつに改行コードを喰わせてやれば行けるんじゃないでしょうか。
mjk

2022/11/29 15:27

cin.get(); いけました!ありがとうございます。 後ほどBAさせていただきます。 (回答修正されるならお待ちしてます) 並行して手探りしてて // getchar(); これでもいけるかもしれませんが自信ないです。 あれこれ試してます。
thkana

2022/11/29 15:48

では、回答もさっさと修正しますか... getchar()は一応「Cの世界」用です。なんだったかな、stdio.h(cstdio)とiostreamを混ぜるとなんだか妙な現象が起こるケースがあったような。ちょっと思い出せません。
yumetodo

2022/11/29 16:01

競技プログラミング界隈でよく見るsync_with_stdioを切ったときは動かないでしょうね
mjk

2022/11/29 17:21

回答とコメントありがとうございました。 cin.get()とgetchar()とsync_with_stdioを切ったときなどをあれこれ試してみます。

0

cin >> N;(cin >> N).get(); または
char c; cin >> N >> noskipws >> c >> skipws; にする。
あるいは、string s; getline(cin, s); N = stoi(s); にする。

投稿2022/11/29 15:49

kazuma-s

総合スコア8080

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

mjk

2022/11/29 17:24

回答ありがとうございます。 (cin >> N).get();というのも良さそうですね。 他のも試してみます。 先に回答とコメントして頂いた方いたのでそちらへBAさせて頂きました。

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
86.12%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。