C++の標準入力について

AI実装検定のご案内

C++の標準入力とは、プログラムの外部から値を受け取るための仕組みです。

たとえば、プログラムを実行したあとにキーボードから数字や文字を入力し、その内容をプログラム内で使うことができます。

競技プログラミングや学習用のコンソールプログラムでは、標準入力を使ってデータを受け取る場面が非常に多くあります。

標準入力は、必ずしもキーボードからの入力だけを指すわけではありません。

ファイルの内容や、オンラインジャッジの入力データなども標準入力として扱われます。

プログラム側では、入力元がキーボードでもファイルでも、基本的には同じ方法で読み取れます。

目次

C++で標準入力を扱う基本

基本的には cin を使う

C++で標準入力を受け取るときは、基本的に cin を使います。

cin は、入力された値を変数に読み込むためのものです。

整数、小数、文字、文字列など、さまざまな型のデータを受け取ることができます。

たとえば、整数を入力すれば整数型の変数に入り、文字列を入力すれば文字列型の変数に入ります。

C++では、変数の型に合わせて入力内容を読み取ってくれるため、基本的な入力処理は比較的分かりやすく書けます。

複数の値もまとめて読み取れる

標準入力では、1つの値だけでなく、複数の値を続けて読み取ることもできます。

たとえば、2つの整数が入力される場合、それぞれ別の変数に順番に読み込めます。

入力が半角スペースで区切られていても、改行で区切られていても、多くの場合は同じように扱えます。

C++の cin は、基本的に空白、改行、タブなどを区切りとして入力を読み取ります。

そのため、次のような入力でも、値を順番に受け取れます。

  • 同じ行に複数の値が並んでいる入力
  • 値ごとに改行されている入力
  • 空白やタブで区切られている入力

この性質を理解しておくと、競技プログラミングや練習問題の入力形式を読み解きやすくなります。

標準入力で読み取れる主なデータ

整数

整数を受け取る場合は、整数型の変数を用意して入力を読み取ります。

小さな整数であれば int がよく使われます。

ただし、入力される値が非常に大きい場合や、合計値が大きくなる可能性がある場合は、long long を使う方が安全です。

目安として、int は約マイナス21億からプラス21億程度まで扱えます。

一方、long long はそれよりはるかに大きい整数を扱えます。

特に競技プログラミングでは、入力値そのものは int に収まっていても、合計や積を計算すると int の範囲を超えることがあります。

そのため、合計値や大きな計算結果を扱う場合は、最初から long long を検討するとよいです。

小数

小数を受け取る場合は、主に double を使います。

円の面積、平均値、割合、距離、時間など、小数を含む計算では double がよく使われます。

ただし、小数は整数と違い、内部的に完全に正確な値として扱えない場合があります。

そのため、小数の比較や出力桁数には注意が必要です。

文字

1文字だけを受け取りたい場合は、文字型を使います。

通常の入力方法では、空白や改行を読み飛ばして、次に現れる文字を読み取ります。

そのため、スペースそのものや改行そのものを文字として扱いたい場合は、通常の読み取り方法とは別の方法を使う必要があります。

初心者のうちは、アルファベットや記号など、空白以外の1文字を読み取る場面で使うと考えると分かりやすいです。

文字列

空白を含まない文字列を受け取る場合は、文字列型を使います。

たとえば、名前、単語、ID、英単語などを入力として受け取るときに使います。

ただし、通常の入力方法では、空白が出てきた時点で文字列の読み取りが終わります。

そのため、「Taro Yamada」のように空白を含む文字列をそのまま1つのデータとして受け取りたい場合は、1行まるごと読み取る方法を使う必要があります。

cingetline の違い

cin は空白まで読み取る

cin で文字列を読み取る場合、基本的には空白までの文字列を受け取ります。

たとえば、入力が「Taro Yamada」のように空白を含む場合、最初の「Taro」だけが読み取られます。

「Yamada」はその時点ではまだ読み取られず、入力側に残ります。

そのため、空白を含まない単語や短い文字列を受け取る場合は cin で十分ですが、文章やフルネームのように空白を含む可能性がある入力には向いていません。

getline は1行まるごと読み取る

空白を含む文章や名前を読み取りたい場合は、getline を使います。

getline は、改行までの内容を1つの文字列として読み取ります。

そのため、「Hello C++ World」のような空白を含む文章でも、1行全体をまとめて受け取れます。

文章、住所、コメント、フルネームなど、空白を含む可能性がある入力を扱う場合は、getline を使うとよいです。

cingetline を混ぜるときは注意が必要

C++の標準入力で初心者がよくつまずくのが、cin の後に getline を使うケースです。

cin で数値や単語を読み取ると、その後ろにある改行文字が入力側に残ることがあります。

その直後に getline を使うと、残っていた改行だけを読み取ってしまい、期待した文字列が取得できない場合があります。

たとえば、最初に年齢を読み取り、その次に名前を1行で読み取りたい場合、年齢の入力後に残った改行を処理してから getline を使う必要があります。

改行を読み飛ばす処理を入れると安全

cin の後に getline を使う場合は、入力側に残っている改行を読み飛ばす処理を入れるのが一般的です。

単に1文字だけ読み飛ばす方法もありますが、より安全にするなら、次の改行までの文字をまとめて読み飛ばす考え方を使います。

記事として説明する場合は、「cin の直後に getline を使うときは、残った改行を捨てる必要がある」と覚えておくと分かりやすいです。

配列や複数データの入力

複数の整数を読み取る

複数の整数を受け取る場合は、まずデータの個数を読み取り、その個数分だけ繰り返し入力を受け取る形がよく使われます。

たとえば、最初に「データの個数」が入力され、その後に複数の整数が並ぶ形式です。

このような場合は、入力された個数に合わせて、繰り返し処理で順番に値を読み取ります。

固定長配列より vector が安全

C++では配列を使って複数の値を管理できますが、固定長の配列はサイズに注意が必要です。

たとえば、あらかじめ100個分の配列を用意していたとしても、入力される個数が100を超えると範囲外アクセスになってしまいます。

これはプログラムの不具合や予期しない動作につながります。

そのため、入力される個数に応じて要素数を変えたい場合は、vector を使う方が安全です。

vector は、必要な個数に合わせてデータを管理しやすいため、C++の学習や競技プログラミングでは非常によく使われます。

2次元の入力も扱える

表のようなデータを読み取る場合は、2次元のデータ構造を使います。

たとえば、縦が3行、横が4列の数値データが与えられる場合、行と列を順番に処理しながら値を読み取ります。

迷路、地図、盤面、表形式の数値などを扱う問題では、2次元の入力がよく登場します。

文字のグリッドは文字列の配列として読むと便利

迷路や盤面のように、各行が文字で構成されている入力では、各行を文字列として読み取る方法が便利です。

たとえば、ドットやシャープで構成されたマップを扱う場合、1行ずつ文字列として受け取ると、あとから「何行目の何列目の文字か」を簡単に参照できます。

競技プログラミングでは、文字のグリッドを文字列の配列として扱う場面が非常に多いです。

EOFまで入力を読み取る方法

入力の個数が分からない場合

入力の個数があらかじめ決まっていない場合は、入力が続く限り読み取り続ける方法を使います。

このような書き方は、ファイルの終わりまでデータを読む場合や、行数が指定されていない入力を処理する場合に使われます。

入力に成功している間だけ処理を続け、入力が終わったら自動的に終了するイメージです。

EOFとは

EOFとは、「End Of File」の略で、入力の終わりを意味します。

ファイルから入力している場合は、ファイルの最後に到達したときがEOFです。

キーボードから入力している場合は、ユーザーがEOFを示す操作を行うことで入力終了を伝えます。

一般的には、Windowsでは Ctrl + Z のあとにEnter、macOSやLinuxでは Ctrl + D を押すことでEOFを送れます。

1行ずつEOFまで読むこともできる

数値ではなく文章を扱う場合は、1行ずつEOFまで読み取る方法もあります。

この場合、1行ごとに文字列として読み取り、入力が終わるまで処理を繰り返します。

ログデータ、複数行の文章、行数が決まっていないテキストなどを扱うときに便利です。

標準入力を高速化する方法

入力が多い場合は高速化設定を使う

競技プログラミングでは、非常に大量の入力を処理する問題があります。

そのような場合、標準のまま cincout を使うと、処理が遅くなることがあります。

そこで、C++では入出力を高速化する設定を使うことがあります。

よく使われるのは、C++の入出力とC言語の入出力の同期を切る設定と、入力前に出力を自動で更新する結びつきを解除する設定です。

これにより、cincout の処理が速くなる場合があります。

C言語の入出力と混ぜない方がよい

高速化設定を使った場合、cincout と、scanfprintf を混ぜて使うのは避けた方が安全です。

C++の入出力とC言語の入出力の同期を切ることで高速化しているため、両方を混在させると、出力の順序が期待通りにならない可能性があります。

C++で書く場合は、基本的に cincout に統一すると分かりやすいです。

対話型プログラムでは注意が必要

入力前に自動で出力を反映する仕組みを解除すると、対話型のプログラムでは注意が必要です。

たとえば、「名前を入力してください」と表示してからユーザーに入力してもらうようなプログラムでは、表示がすぐに反映されないことがあります。

競技プログラミングの通常問題ではあまり問題になりませんが、ユーザーと対話しながら進むプログラムでは、必要に応じて出力を明示的に反映させる必要があります。

cinscanf の違い

C++では基本的に cin を使えばよい

C++では、標準入力には基本的に cin を使えば問題ありません。

cin は、変数の型に応じて入力を読み取ってくれるため、初心者にも扱いやすいです。

整数、文字列、小数などを自然な形で読み取れます。

一方、C言語では scanf がよく使われます。

C++でも scanf を使うことはできますが、C++を学習している段階では、まず cin に慣れる方がよいでしょう。

大量入力では速度を意識する

昔は、cin よりも scanf の方が速いと言われることが多くありました。

しかし、C++でも高速化設定を使えば、cin で十分高速に処理できる場面が多くあります。

競技プログラミングでも、現在は高速化設定を入れたうえで cincout を使う人が多くいます。

標準入力でよくある入力パターン

整数を1つ読み取る

最も基本的なパターンです。

入力として整数が1つだけ与えられる場合、その値を変数に読み取って使います。

たとえば、年齢、個数、点数、回数などを受け取る場面で使います。

整数を2つ読み取る

2つの整数が並んで入力されるパターンもよくあります。

たとえば、横幅と高さ、2つの数の和、開始位置と終了位置などを扱う場合です。

入力が同じ行にあっても、改行されていても、基本的には順番に読み取れます。

N個の整数を読み取る

最初にデータ数 N が与えられ、そのあとに N 個の整数が並ぶ形式です。

競技プログラミングやアルゴリズムの練習問題では非常によく登場します。

合計を求める、最大値を求める、条件に合う数を数える、並べ替えるといった処理で使われます。

文字列を1つ読み取る

空白を含まない文字列を1つ読み取るパターンです。

単語、名前、ID、コマンド、英小文字の文字列などを扱う場合に使います。

ただし、空白を含む文字列には向いていないため、その場合は1行まるごと読み取る方法を使います。

複数の文字列を読み取る

最初に文字列の個数が与えられ、そのあとに複数の文字列が入力される形式です。

たとえば、単語リスト、名前一覧、商品名一覧などを扱う場合に使います。

各文字列が空白を含まない場合は、通常の入力方法で順番に読み取れます。

1行の文章を読み取る

空白を含む文章を扱う場合は、1行まるごと読み取る方法を使います。

コメント、メッセージ、フルネーム、住所などを受け取るときに使えます。

ただし、直前に数値などを通常の方法で読み取っている場合は、残った改行に注意が必要です。

H行W列の数値を読み取る

表形式の数値データを読み取るパターンです。

最初に行数と列数が与えられ、そのあとに各マスの数値が入力されます。

行と列を二重に処理しながら読み取ることで、表形式のデータを扱えます。

H行W列の文字グリッドを読み取る

迷路や盤面のような入力では、各行を文字列として読み取る方法がよく使われます。

たとえば、通れる場所をドット、壁をシャープで表すような問題です。

各行を文字列として読み取ることで、あとから特定の位置の文字を確認しやすくなります。

標準入力でよくあるミス

cingetline の混在ミス

最もよくあるミスのひとつが、cin の後にそのまま getline を使ってしまうことです。

cin で数値や単語を読み取ったあと、入力側に改行が残っていると、getline がその改行を読み取ってしまいます。

その結果、本来読み取りたかった行ではなく、空の文字列が読み取られることがあります。

このような場合は、getline を使う前に、残っている改行を読み飛ばす処理が必要です。

変数の型を間違える

入力される値に対して、変数の型が小さすぎると正しく扱えないことがあります。

たとえば、非常に大きな整数を int に入れようとすると、範囲を超えてしまいます。

また、合計値や掛け算の結果が大きくなる場合も注意が必要です。

入力値の範囲が大きい場合や、計算結果が大きくなりそうな場合は、long long を使うと安全です。

配列のサイズを間違える

固定長配列を使う場合、用意した配列のサイズを超えて入力を読み取ると危険です。

たとえば、10個分しか用意していないのに、20個のデータを読み込もうとすると、範囲外アクセスになります。

入力されるデータ数が変わる場合は、固定長配列よりも vector を使う方が安全です。

入力形式をよく確認しない

標準入力では、入力形式を正しく読むことが非常に重要です。

最初に何が入力されるのか、次に何個のデータが来るのか、各行にはどのような値が並んでいるのかを確認してからコードを書く必要があります。

たとえば、最初の数値が「人数」を表しているのか、「行数」を表しているのか、「テストケース数」を表しているのかによって、その後の読み取り方が変わります。

空白を含む文字列を通常の方法で読もうとする

空白を含む文字列を読み取りたいのに、通常の文字列入力を使ってしまうと、空白までしか読み取れません。

文章やフルネームのように、空白を含む可能性がある入力では、1行まるごと読み取る方法を使う必要があります。

合計値の型を小さくしてしまう

複数の数値の合計を求める場合、1つ1つの値は小さくても、合計すると大きな値になることがあります。

そのため、合計を保存する変数には long long を使った方が安全なケースがあります。

特に、入力の個数が多い問題では注意が必要です。

標準入力を理解するコツ

入力形式を分解して考える

標準入力を扱うときは、まず入力形式を分解して考えることが大切です。

見るべきポイントは、主に次のような点です。

最初に何が入力されるのか、データは何個あるのか、各行には何が並んでいるのか、文字列に空白は含まれるのか、数値の範囲はどのくらいか。

これらを確認すると、どの型の変数を用意すればよいか、何回繰り返して読み取ればよいかが分かりやすくなります。

入力の順番通りに読み取る

標準入力では、基本的に入力された順番通りにデータを読み取ります。

最初に個数が入力されるなら、まず個数を読み取ります。

次に、その個数分のデータが続くなら、繰り返し処理で順番に読み取ります。

入力形式とコードの読み取り順がずれていると、正しく値を受け取れません。

型を先に決めてから読む

入力値が整数なのか、小数なのか、文字列なのかによって、使う型が変わります。

整数なら intlong long、小数なら double、文字列なら string、1文字なら char を使います。

また、入力値の範囲が大きい場合は、最初から大きな型を使うことも大切です。

空白を含むかどうかを確認する

文字列入力では、空白を含むかどうかが重要です。

空白を含まない単語であれば通常の文字列入力で問題ありません。

一方、空白を含む文章や名前を読み取りたい場合は、1行まるごと読み取る必要があります。

ここを間違えると、入力の一部しか読み取れないことがあります。

初心者がまず覚えるべきポイント

数値や単語は cin で読む

整数、小数、空白を含まない文字列などは、基本的に cin で読み取ります。

最初のうちは、標準入力といえばまず cin を使う、と考えて問題ありません。

文章は getline で読む

空白を含む文章や1行全体を読みたい場合は、getline を使います。

ただし、直前に cin を使っている場合は、残った改行に注意が必要です。

複数データは繰り返しで読む

入力されるデータが複数ある場合は、繰り返し処理を使って順番に読み取ります。

最初にデータ数が与えられる形式では、その個数分だけ繰り返して入力を受け取るのが基本です。

大きな数には long long を使う

入力値や計算結果が大きくなる可能性がある場合は、int ではなく long long を使うと安全です。

特に合計や掛け算を行う場合は、オーバーフローに注意しましょう。

入力形式をよく読む

標準入力では、入力形式を正しく理解することが何より重要です。

どの順番で、どの型のデータが、何個入力されるのかを確認してからコードを書くようにすると、ミスを減らせます。

まとめ

C++の標準入力は、プログラムの外部からデータを受け取るための基本的な仕組みです。

数値や空白を含まない文字列を読み取る場合は、主に cin を使います。

空白を含む文章や1行全体を読み取りたい場合は、getline を使います。

ただし、cingetline を続けて使う場合は、入力側に残った改行に注意が必要です。

cin で数値や単語を読み取った直後に getline を使うと、改行だけを読み取ってしまうことがあります。

また、複数のデータを読み取る場合は、入力形式に合わせて繰り返し処理を使います。

配列よりも vector を使うと、入力数に応じて柔軟にデータを管理できます。

大量の入力を扱う場合は、入出力の高速化設定を使うこともあります。

ただし、その場合は cin / coutscanf / printf を混ぜない方が安全です。

C++の標準入力を理解するうえで大切なのは、入力形式をよく読み、「どの型の変数に、どの順番で、何個のデータを読み込むのか」を整理することです。

最初は難しく感じるかもしれませんが、基本パターンに慣れれば、標準入力は自然に扱えるようになります。

以上、C++の標準入力についてでした。

最後までお読みいただき、ありがとうございました。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次