C言語のprintfやscanfに慣れていると、C++の標準入出力は少し雰囲気が違って見えるかもしれません。
本記事ではC++の標準入出力(ostreamのcout、istreamのcin)を、演算子の意味から具体的な入力・出力の実例まで、段階を踏んで丁寧に解説します。
最後まで読めば、日常的な入出力処理は自信を持って書けるようになります。
C++の標準入出力の基本
標準入出力とは
コンソールプログラムは、キーボードからの入力と画面への出力を通じてユーザーとやり取りします。
C++ではstd::cin
が標準入力、std::cout
が標準出力、std::cerr
がエラー出力です。
標準入出力はデバイスやファイルにリダイレクト可能で、同じコードのまま入出力先を切り替えられる柔軟性があります。
iostreamをインクルードする
入出力ストリームを使うには#include <iostream>
が必要です。
名前空間はstd::
を明示して使います。
初心者は「using namespace std;」を安易に使わないほうが、名前衝突を避けられて安全です。
#include <iostream> // cout, cin, endl などの宣言が入っている
int main() {
std::cout << "準備完了\n";
return 0;
}
準備完了
coutとcinの役割
std::cout
は「出力用のストリーム(流れ)」、std::cin
は「入力用のストリーム」です。
データはストリームに対して「挿入する」「抽出する」という操作でやり取りします。
C言語のprintf/scanf
のようなフォーマット指定ではなく、型に応じた入出力が演算子の多重定義で提供されています。
演算子(<<, >>)の意味
std::cout << 値
は「ストリームへの挿入(出力)」、std::cin >> 変数
は「ストリームからの抽出(入力)」を表します。
ビット演算の<<
や>>
とは意味が異なり、ストリーム向けに演算子がオーバーロードされている点がC++らしい特徴です。
最小サンプル(Hello World)
最小構成での出力例です。
改行には'\n'
やstd::endl
が使えます(違いは後述します)。
#include <iostream>
int main() {
// 文字列リテラルを出力し、改行文字で行を終える
std::cout << "Hello, World!" << '\n';
return 0;
}
Hello, World!
coutの使い方(出力)
文字列を出力する
文字列リテラルはダブルクオートで囲みます。
std::string
もそのまま出力できます。
#include <iostream>
#include <string>
int main() {
std::cout << "文字列リテラルの出力" << '\n';
std::string name = "Taro"; // C++の安全な文字列型
std::cout << "名前: " << name << '\n'; // std::stringも<<で出力可能
}
文字列リテラルの出力
名前: Taro
C++ではstd::string
が推奨です。
C言語の生配列文字列(char配列)は扱いが難しくバッファあふれの危険があるため、初心者は避けると安全です。
数値を出力する
整数や浮動小数点数はそのまま<<
で出力できます。
#include <iostream>
int main() {
int a = 42;
double pi = 3.14159;
bool ok = true;
std::cout << "a=" << a << '\n';
std::cout << "pi=" << pi << '\n';
std::cout << "ok=" << ok << '\n'; // デフォルトでは true は 1, false は 0
std::cout << std::boolalpha; // 真偽値を true/false で出すマニピュレータ
std::cout << "ok=" << ok << '\n';
}
a=42
pi=3.14159
ok=1
ok=true
複数の値をつなぐ(<<の連結)
<<
は左から右へと「連鎖」させて書けます。
フォーマット指定子を数えたり型を意識したりする必要がなく、読みやすいのが利点です。
#include <iostream>
#include <string>
int main() {
std::string item = "Apple";
int price = 150;
int qty = 3;
std::cout << "商品: " << item << ", 単価: " << price
<< "円, 数量: " << qty << ", 小計: " << price * qty << "円\n";
}
商品: Apple, 単価: 150円, 数量: 3, 小計: 450円
改行の書き方(基本)
改行には'\n'
またはstd::endl
を使います。
std::endl
は改行に加えてバッファをフラッシュ(強制書き出し)するため、頻繁に使うと遅くなります。
通常は'\n'
が推奨です。
以下は違いの早見表です。
方法 | 何をするか | フラッシュ | 相対的な速度 | 主な用途 |
---|---|---|---|---|
‘\n’ | 改行コードを書くだけ | しない | 速い | 通常の改行 |
std::endl | 改行してフラッシュ | する | 遅い | 直後に表示させたいログ、対話入出力で即時反映 |
#include <iostream>
#include <thread>
#include <chrono>
int main() {
std::cout << "改行のみ(\\n)" << '\n'; // ほぼ常にこれでOK
std::cout << "即時表示したいときはendlでフラッシュ" << std::endl;
// 例: プログレス的に即時表示したいケース
std::cout << "処理中..." << std::flush; // 明示フラッシュも可能
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::cout << "完了" << '\n';
}
改行のみ(\n)
即時表示したいときはendlでフラッシュ
処理中...完了
変数を使った出力の例
式の評価結果もそのまま出力できます。
デバッグプリントでもよく使います。
#include <iostream>
int main() {
int x = 7, y = 5;
std::cout << "x=" << x << ", y=" << y << '\n';
std::cout << "x + y = " << (x + y) << '\n';
std::cout << "x * y = " << x * y << '\n';
}
x=7, y=5
x + y = 12
x * y = 35
cinの使い方(入力)
数値を読む(整数, 小数)
std::cin >> 変数
は、空白(スペース・改行・タブ)で区切られたトークンを読みます。
変数の型に合う形で自動的に変換されるのがポイントです。
#include <iostream>
int main() {
int n;
double d;
std::cout << "整数と小数をこの順に入力してください: " << std::flush; // 促し
if (std::cin >> n >> d) { // 2つとも読めたらtrue
std::cout << "n=" << n << ", d=" << d << '\n';
} else {
std::cout << "読み取りに失敗しました" << '\n';
}
}
10 3.14
n=10, d=3.14
文字列を読む(空白なし)
std::string
へ>>
で読むと、最初の空白までが1単語として取り込まれます。
#include <iostream>
#include <string>
int main() {
std::string word;
std::cout << "単語を入力してください: " << std::flush;
std::cin >> word; // 空白で区切られる
std::cout << "入力された単語: " << word << '\n';
}
C++初心者
入力された単語: C++初心者
行全体を読む(getline)
スペースを含めて1行まるごと読みたい場合はstd::getline
を使います。
#include <iostream>
#include <string>
int main() {
std::string line;
std::cout << "1行入力してください: " << std::flush;
std::getline(std::cin, line); // 改行までをまとめて取得
std::cout << "行の内容: " << line << '\n';
}
Hello C++ world with spaces
行の内容: Hello C++ world with spaces
cinとgetlineを一緒に使うコツ
operator>>
は数値や単語を読み終えると、区切りの改行を読み残します。
その直後にstd::getline
を呼ぶと、残っている改行を空行として読んでしまうことがあります。
対策としてstd::ws
で前の空白をスキップします。
#include <iostream>
#include <string>
int main() {
int age;
std::string name;
std::cout << "年齢を入力: " << std::flush;
std::cin >> age; // ここで末尾の改行がバッファに残る
std::cout << "フルネームを入力: " << std::flush;
std::getline(std::cin >> std::ws, name); // std::wsで先頭空白(含: 改行)を除去
std::cout << "年齢=" << age << ", 名前=" << name << '\n';
}
20
Yamada Taro
年齢=20, 名前=Yamada Taro
入力の成否を確認する(基本)
入力は常に失敗の可能性があります。
if (std::cin >> x)
の形で成否を判定したり、エラー時はstd::cin.clear()
とstd::cin.ignore()
で復帰します。
#include <iostream>
#include <limits> // numeric_limits
int main() {
int value;
std::cout << "整数を入力してください: " << std::flush;
if (!(std::cin >> value)) { // 失敗ならストリームはfail状態になる
std::cout << "整数として読み取れませんでした" << '\n';
std::cin.clear(); // エラー状態を解除
// 残ったゴミを行末まで捨てる
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
return 1;
}
std::cout << "入力値は " << value << " です" << '\n';
}
abc
整数として読み取れませんでした
初心者がつまずくポイント
スペースを含む入力の注意
スペースを含む文字列はoperator>>
では途中で切れるため、必ずstd::getline
を使います。
数値の後で行入力に切り替える場合はstd::ws
で残留改行を捨てることを忘れないようにしましょう。
これを怠ると「いきなり空の行が読まれた」ように見えます。
型の不一致で読み取り失敗
intに文字列、doubleに「3,14」のようなロケール違いを入れるとfailbit
が立ち、以後の読み取りが停止します。
失敗時はclear()
で状態を戻し、ignore()
で不正な入力を捨てるのが基本です。
#include <iostream>
#include <limits>
int main() {
int n;
std::cout << "整数を入力(例: 100): " << std::flush;
if (!(std::cin >> n)) {
std::cout << "数値に変換できません。再入力してください。" << '\n';
std::cin.clear(); // fail状態解除
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // 行末まで破棄
return 1;
}
std::cout << "OK: n=" << n << '\n';
}
one hundred
数値に変換できません。再入力してください。
入出力のミニサンプルで練習する
短いプログラムで手を動かすと理解が早まります。
以下は合計と行入力の2本です。
どちらも改行や失敗処理に注目してください。
例1) 2つの整数の和を計算
#include <iostream>
int main() {
int a, b;
std::cout << "2つの整数を入力: " << std::flush;
if (std::cin >> a >> b) {
std::cout << "和 = " << (a + b) << '\n';
} else {
std::cout << "入力エラーです" << '\n';
}
}
12 34
和 = 46
例2) 名前と自己紹介の行入力
#include <iostream>
#include <string>
int main() {
std::string name, bio;
std::cout << "名前: " << std::flush;
std::getline(std::cin, name);
std::cout << "自己紹介(1行): " << std::flush;
std::getline(std::cin, bio);
std::cout << "---- 確認 ----" << '\n';
std::cout << "名前: " << name << '\n';
std::cout << "自己紹介: " << bio << '\n';
}
Hanako
C++が好きで、競技プログラミングを始めました。
---- 確認 ----
名前: Hanako
自己紹介: C++が好きで、競技プログラミングを始めました。
まとめ
C++の標準入出力は、ストリームと演算子の組み合わせで自然な文として書けるのが最大の利点です。
基本はstd::cout << 値
とstd::cin >> 変数
、改行は原則'\n'
、即時表示が必要ならstd::endl
を使います。
スペースを含む文字列はstd::getline
、数値との併用時はstd::ws
で改行を捨てることを覚えておくと安心です。
さらに入力失敗の検出とclear()/ignore()
での復帰を習慣化すれば、実運用でも堅牢な入出力が書けます。
最初は小さなサンプルで確かめながら、少しずつ自分の用途に合わせた入出力に発展させていきましょう。