Cではコンソール入出力の際に、printf()やscanf()といった関数を使っていました。C++でも、これらの入出力関数を使うこともできますが、新しいC++スタイルの入出力演算子(>>および<<)を使用することもできます。ここでは、C++の入出力に関連する内容を説明します。
LIST1-1 (console1.cpp)
includeSrcWithFrame("page1/console1.cpp", 4, "", true, true); ?>
C言語のプログラムでは、ライブラリ関数を使うときにはヘッダファイルをインクルードしていました。例えば、入出力関数用ヘッダファイルのインクルードの際には、プログラムの先頭に以下のように書きました。
#include <stdio.h>
C++でも、このような書き方がサポートされています。しかし、標準C++では、さらに、新しい種類のヘッダが追加されました。新しいスタイルでは、ヘッダファイルではなく、識別子を指定します。".h"が無いことに注意してください。新しいスタイルのヘッダの例として以下のようなものがあります。
<iostream> 入出力関連ヘッダ
<fstream> ファイル入出力関連ヘッダ
※ 識別子とは、変数、関数、クラスなどを個々に識別するためにつける名前のことです。
C言語では、開発するソフトウェアの規模が大きくなるにつれ、他の関数や変数と同じ名前を使用してしまう"名前の競合(もしくは衝突)"の問題が生じました。
C++における"名前空間"は、名前の競合を防ぐ目的で、識別子の名前を局所化するために使用されます。同じ"田中さん"でも"宇都宮の田中さん"と"小山の田中さん"というようにして区別することができますね。この"宇都宮"、"小山"が名前空間に相当すると考えてください。
さて、Cではライブラリ関数の名前などは、グローバルな名前空間に置かれていました。
新しいスタイルのC++ヘッダの内容は std名前空間に置かれています。std名前空間の関数や変数を使用するには「std::cout」のようにスコープ解決演算子を用いる必要があります。
ここで現れた「std::cout」は、C言語でいうstdout(標準出力=コンソール出力:console out)に当たります。
また、「std::endl」は、改行(end of line)を示します。
C++では出力演算子 << と 入力演算子 >> が定義されています。Cでは<<は左シフト、>>は右シフトでした。C++ではシフト演算子としても使用されますが、入出力の演算子としての役割もあります
どちらの機能になるかは、演算子の左側におかれたオブジェクトの型に依ります。演算子の左が数値型であればシフト、入出力ストリームオブジェクトであれば入出力演算になります。これが「演算子 << が多重定義されている」ということの意味です。
なお、C++の入出力演算子を使うには、<iostream>ヘッダをインクルードする必要があります。
LIST1-2 (console2.cpp)
includeSrcWithFrame("page1/console2.cpp", 4, "", true, true); ?>
LIST1-1との違いは、何でしょうか?
以下の文を使用して、std 名前空間をデフォルトで参照可能(可視状態)にすることが出来ます。
using namespace std;
こうすることで、毎回スコープ解決演算子を用いて"std::"と書く必要がなくなります。
つまり、C++スタイルの入出力を使用する場合には、通常、プログラムの先頭に以下のように2行を記述することになります。
#include <iostream>
using namespace std;
もし、C++のコンパイラが古いバージョンで、上記の書き方ではエラーが発生する場合には、次のように1行で書くこともできます。
#include <iostream.h>
この場合はcoutなどはグローバル名前空間におかれます。
.h が付いている点とusing namespace ...の文がない点に注目してください。
LIST1-3 (console3.cpp)
includeSrcWithFrame("page1/console3.cpp", 4, "", true, true); ?>
実行例
整数値を入力してください 5 あなたが入力したのは 5 です 実数値を入力してください 3.141592 あなたが入力したのは ******3.14 です 1文字だけ入力してください a あなたが入力したのは a です 文字列を入力してください hello あなたが入力したのは hello です |
入出力演算子(<<および>>)の右側に、文字列や数値の変数を置くことが出来る、ということに注目してください。
これも「演算子 << が多重定義されている」ということの意味です。
右辺に置いた変数(オブジェクト)の型に応じて、適切に表示してくれる、というのがC++スタイル入出力の良いところです。
一方、Cスタイルのprintfでは、書式文字列(%d,%fや%s)と、引数の型(int型、float型、文字列char[]型)が違うとおかしな表示になります。
ストリーム(stream)という英単語の意味は”流れ”ですね。ここでは、情報を流すための論理デバイスのことを言います。論理デバイスが、CやC++の入出力システムによって物理デバイス(キーボードや画面)とリンクされることでデータを入力したり、表示したりすることができるわけです。
Cでは、出力の際に、以下のように記述していました。
int i;
double d;
fprintf(stdout, "あなたが入力したのは %d です\n", i);
fprintf(stdout, "あなたが入力したのは %lf です\n", d);
printf("あなたが入力したのは %d です\n", i);
printf("あなたが入力したのは %lf です\n", d);
これを、C++では以下のように記述することができます。
cout << "あなたが入力したのは" << i << "です\n";
cout << "あなたが入力したのは" << d << "です" << endl;
書式指定子(%d、%lf など)がないですね。 書式指定子を気にしないでよいのはちょっと嬉しいですね。
C++の定義済みストリームを以下の表にまとめます。
意味 | デフォルトデバイス | Cとの対応 | |
cin | 標準入力 | キーボード | stdin |
cout | 標準出力 | 画面 | stdout |
cerr | 標準エラー出力 | 画面 | stderr |
clog | バッファを使うcerr | 画面 |
入出力マニピュレータ(I/O manipulator)とは、入出力ストリームに対して使用できるオブジェクトです。先ほど登場した endl は改行文字(\n)を出力し、ストリームをフラッシュする入出力マニピュレータです。よく使用する入出力マニピュレータと、その使用例、実行結果を以下の表にまとめます。
なお、setw()のように仮引数をとるマニピュレータを使用するには<iomanip>をインクルードしておく必要があります。
目的 | 例 | 実行結果 | |
endl | 改行文字(\n)を出力し、 ストリームをフラッシュ |
cout << "hello" << endl; | hello |
hex | hexフラグをオン | cout << hex << 255; | ff |
oct | octフラグをオン | cout << oct << 9; | 11 |
setw(int w) | フィールド幅をwに設定 | cout << setw(5) << 35; | ___ 35 ※注 |
setprecision(int p) | 精度の桁数をpに設定 | cout << setprecision(3) << 2.5614; | 2.56 |
setfill(int ch) | 充填文字をchに設定 | cout << setfill('*') << setw(4) << 5; | ***5 |
※注 ___ は半角スペース3つを表す。
ファイル入出力の必要がある場合、入力ファイルが1つ・出力ファイルが1つまでであれば、コンソール入出力をファイルにつなぎかえる「リダイレクト機能」により、大抵の用事は済ますことが出来ます。リダイレクトの復習(プログラミング演習Iデバッガ)
ただし、ファイルを複数扱う場合や、ファイル中の場所を指定して一部だけを読み書きしたい場合には、プログラムの中でファイルを扱うための「ファイル入出力」の機能を使用する必要があります。
ファイル入出力については、教科書9章以降で扱っているので、余裕のある人は読んでおくと良いでしょう。
おまけ:プログラミング演習コラム by大川タッチタイピング情報技術者を志すものであれば、必ず身に着ける必要がある。プログラミングや書類の作成において、必要になる技術なので、身に着けて損はないというか、必ず身に着けるべし。 私はインターネット上のタイピング練習(無料)サイトで身に着けた(あと、当時流行した北斗の拳タイピング)。身に着けることで受ける利益は大変大きい。 C++を学ぶ意義コンピュータの動きを理解するためにはC言語を学ぶと良い。それは、基本的にマイクロプロセッサが出来る事は「メモリに対して読み書きし演算することだけ」ということが理解できるからである。メモリ上の数値をいじくるだけで、これだけ多彩なことが出来る、という発見は大きな驚きだと思う。 変数はメモリ上に配置されるものである、という理解があれば、ポインタというのはメモリ上に配置された変数のアドレスなのだ、と納得できるであろう。理解が難しいとされるポインタも大したことはない。より納得感を得るためには、アセンブリ言語も学ぶと良い。(情報工学実験Iのマイコン実習の理解を深めればよい) さてそれでは、C++を学ぶ意義とは何か? 「C++は、1983年にベル研究所のコンピュータ科学者であったビャーネ・ストロヴストルップが、C言語の拡張として開発した。(出典:Wikipedia日本語版)」 その後、長い期間、世界中で使われているからには何らかの理由があるはずである。 自分にとってどのような良いことがあるかは、各自で考えて欲しい。ただここでは、いくつかの情報を示すこととする。 世の中で使われている開発言語(世界編)TIOBE Programming Community Index May 2014 ![]() ![]() 世の中で使われている開発言語(日本編)プログラミング言語別 年収・求人数ランキング(2010年版) 【株式会社ワークポート調べ「2010年IT業界の転職市場」】![]() |