コンパイル時に「error C2065: 'cout': 定義されていない識別子です。」のようにエラーとなるならば、using namespace std;
としてusingディレクティブで指定するか、std::cout
として名前空間を指定します。
char (バイト単位) | wchar_t (ワイド単位) | |||
---|---|---|---|---|
入力 | 出力 | 入力 | 出力 | |
文字 | istream | ostream | wistream | wostream |
ファイル | ifstream | ofstream | wfstream | wofstream |
文字列 | istringstream | ostringstream | wistringstream | wostringstream |
typedef basic_istream<char, char_traits<char>> istream; typedef basic_ifstream<char, char_traits<char>> ifstream; typedef basic_istringstream<char> istringstream;
char (バイト単位) |
wchar_t (ワイド単位) |
|
---|---|---|
入力 | std::cin cin | MSDN |
std::wcin wcin | MSDN |
出力 | std::cout cout | MSDN |
std::wcout wcout | MSDN |
エラー出力 (バッファリングなし) | std::cerr | std::wcerr |
エラー出力 (バッファリング付き) | std::clog | std::wclog |
std::istream std::cin; std::ostream std::cout; std::ostream std::cerr; std::ostream std::clog;include\iostream
coutは、既定でcinに結合されています。
std::ostream* os1 = std::cin.tie();
std::ostream* os2 = &std::cout;
(os1 == os2); // true
typedef basic_istream<char, char_traits<char>> istream;istream | MSDN
typedef basic_ostream<char, char_traits<char>> ostream;ostream | MSDN
ostreamは、以下の定義済みストリームオブジェクトをサポートします。
#include <iostream> int main() { char* str = "abc"; int num = 123; std::cout << str << num << std::endl; // abc123 std::cout << 1.0 / 6.0 << std::endl; // 0.166667 }
出力に予期しない修正が加えられる場合には、書式設定を確認します。
ストリームに文字列を出力できます。
basic_ostream<_Elem, _Tr>& write( const char_type* str, streamsize count );basic_ostream::write - basic_ostream クラス
const char str[] = "12345";
std::streamsize count = 3;
std::cout.write(str, count); // 123
wchar_tを対象としたostreamです。
typedef basic_ostream<wchar_t, char_traits<wchar_t>> wostream;wostream | MSDN
正しく出力されない場合には、imbue()でロケールを設定します。
これはwchar_t型の文字を出力するためのストリームであり、ワイド文字であってもcharに格納されているならばostreamで出力できます。
char *s1 = "あ"; std::cout << s1; // あ std::wcout << s1; // あ wchar_t *s2 = L"あ"; std::cout.imbue(std::locale(".932")); std::wcout.imbue(std::locale(".932")); std::cout << s2; // *,***,***,***,***,*** (s2のアドレス) std::wcout << s2; // あ
ファイルストリーム。ファイルから1バイトのデータを順番に読み取れます。ifstream | MSDN
std::ifstream stream("sample.txt"); if (!stream.bad()) { std::cout << stream.rdbuf(); stream.close(); // ファイルのクローズ。ただしデストラクタによって暗黙的に実行されるため、通常は不要 }
このifstreamは、
typedef basic_ifstream<char, char_traits<char>> ifstream;
と宣言されているため、
std::basic_ifstream<char, std::char_traits<char>> stream("sample.txt");
としても同じです。
ストリーム バッファのアドレスを取得できます。
basic_filebuf<Elem, Tr> *rdbuf( ) constbasic_ifstream::rdbuf | MSDN
typedef basic_ofstream<char, char_traits<char>> ofstream;ofstream | MSDN
#include <fstream> int main() { std::ofstream stream("sample.txt"); // fstreamではなくiostreamだけをインクルードしていると、Visual Studioは「不完全な型は使用できません」と通知します。 if (!stream.bad()) { stream << "ABC" << std::endl; stream.close(); } }
ストリームを開くときに、引数でモードなどを指定できます。
explicit basic_ofstream( const char *_Filename, ios_base::openmode _Mode = ios_base::out, // 通信方法 int _Prot = (int)ios_base::_Openprot // 保護方法 (PROTection) );basic_ofstream::basic_ofstream | MSDN
_Modeには下表の値を組み合わせて渡せます。
値 | |
---|---|
std::ios::app | 挿入前にストリームの末尾へ移動 |
std::ios::ate | 作成するときにストリームの末尾へ移動 |
std::ios::binary | バイナリとして読み込む |
std::ios::in | ストリームからの抽出を許可 (読み込み用) |
std::ios::out | ストリームへの挿入を許可 (書き込み用) |
std::ios::trunc | 既存のファイルを削除 |
ストリームに対してstd::endlを出力すると、改行記号 (\n または \r\n) が出力されフラッシュされます。endl | MSDN
stream << std::endl;
wofstreamで正しく出力されないときには、imbue()でロケールを明示します。
std::wofstream stream("sample.txt"); stream.imbue(std::locale("", LC_CTYPE)); if (!stream.bad()) { std::wstring str = L"あいう"; stream << str; stream.close(); }
fstreamにはファイルをロックする機能が無いため、同一のファイルへ書き込むと予期せぬ結果をもたらします。
char* filename = "sample.txt";
std::ofstream stream1(filename, std::ios::out | std::ios::trunc);
std::ofstream stream2(filename, std::ios::out | std::ios::trunc);
stream1 << "A";
stream2 << "B";
stream1 << "C";
stream1.flush();
stream2.flush();
stream1.close();
stream2.close();
// ファイルには"BC"と書き込まれる。
一方で、外部でロックされているファイルに書き込んでも失敗します。そのときエラーは発生しませんが、書き込み用にストリームを開いた時点でstream.good()がfalseを返すため、それで異常を検知できます。
文字列ストリーム
typedef basic_istringstream<char> istringstream;istringstream - <sstream> typedefs | Microsoft Learn
typedef basic_ostringstream<char> ostringstream;ostringstream - <sstream> typedefs | Microsoft Learn
std::ostringstream stream; stream << "ABC";
メンバ関数 | trueを返す条件 | 等価な表現 |
---|---|---|
basic_ios::good() | ストリームが良い状態 basic_ios::good | MSDN | if(rdstate == goodbit) |
basic_ios::bad() | ストリーム バッファの健全性が失われている basic_ios::bad | MSDN | if(rdstate & badbit) |
basic_ios::eof() | ストリームの末尾に到達している basic_ios::eof | MSDN | if(rdstate & eofbit) |
basic_ios::fail() | 有効なフィールドの読み込に失敗している basic_ios::fail | MSDN | if(rdstate & (badbit|failbit)) |
basic_ofstream::is_open() | ファイルが開かれている basic_ofstream::is_open | MSDN | rdbuf->is_open() |
異常な状態となったときに、例外を投げるように指示できます。
iostate exceptions( ) const;
void exceptions( iostate _Newexcept );basic_ios::exceptions | MSDN
値 | 発生要因 |
---|---|
std::ios::badbit | バッファの健全性の欠如 |
std::ios::eofbit | ファイル末尾からの読み込み |
std::ios::failbit | 無効なフィールドの読み込み |
std::ifstream stream; stream.exceptions(std::ios::badbit | std::ios::eofbit | std::ios::failbit);
投入される例外はexception型で捕捉でき、その内容はwhat()で確認できます。exception クラス | MSDN
std::cout.exceptions(std::ios::eofbit); try { std::cout.clear(std::ios::eofbit); } catch (std::exception &e) { std::cerr << e.what(); }
wchar_t型の文字が正しく処理されないときには、imbue()でロケールを指定します。
wchar_t s1 = L'a'; std::cout << s1; // 97 ('a'のASCIIコード) std::wcout << s1; // a wchar_t *s2 = L"a"; std::cout << s2; // **************** (s2のアドレス) std::wcout << s2; // a wchar_t *s3 = L"あ"; std::wcout.imbue(std::locale(".932", LC_CTYPE)); std::wcout << s3; // あ (ロケールを指定しないと、出力されないことがある)
ロケールを変更できます。これはCランタイムのsetlocale()に相当します。Differences between the C Locale and the C++ Locales
locale imbue( const locale& _Loc );basic_ios::imbue - basic_ios クラス | Microsoft Learn
たとえば環境の既定値に設定するには、引数の_Locに次のように指定します。
std::wcout.imbue(std::locale("", LC_CTYPE));
ここで指定するlocaleクラスは、次のように作成できます。
explicit locale( const char* _Locname, // ロケールの名前 category _Cat = all // ロケールのカテゴリ );locale::locale - locale Class | Microsoft Learn
_Locnameは次のいずれかの形式で指定します。Locale Names, Languages, and Country-Region Strings | Microsoft Learn
_Catでlocale::categoryにある値を指定することで、適用範囲を制限できます。
ロケール | 適用範囲 | コード |
---|---|---|
英語-米国 | すべての関数 | std::locale("en-US") |
日本語-日本 | すべての関数 | std::locale("ja-JP") |
日本語 | すべての関数 | std::locale("Japanese") |
コードページ 932 (Shift-JIS) | すべての関数 | std::locale(".932") |
コードページ 932 (Shift-JIS) | 文字列処理関数だけ | std::locale(".932", LC_CTYPE) |
ストリームに格納されているlocaleオブジェクトを得られるため、そこから現在のロケールを確認できます。
std::locale l1 = std::cout.getloc(); std::locale l2 = std::locale(); // global localeに一致したlocaleオブジェクトを作成する std::string str1 = l1.name(); // "C" std::string str2 = l2.name(); // "C" std::cout.imbue(std::locale(".932", LC_CTYPE)); // ロケールを設定する std::string str3 = std::cout.getloc().name(); // ".932"
codecvt_utf8を用います。 codecvt_utf8 | MSDN c++ - What is the Windows equivalent for en_US.UTF-8 locale? - Stack Overflow
std::wcout.imbue( std::locale( std::wcout.getloc(), new std::codecvt_utf8<wchar_t>) );
このときFacet型のクラス テンプレートを引数に取る、localeのコンストラクタが呼び出されます。
template<class Facet> locale( const locale& _Loc, const Facet* _Fac );locale::locale | MSDN
さらにBOMを付けて出力するには、Modeにgenerate_headerを指定します。
std::wcout.imbue( std::locale( std::wcout.getloc(), new std::codecvt_utf8<wchar_t, 0x10ffff, std::codecvt_mode::generate_header>) );
codecvt_mode | |
---|---|
std::codecvt_mode::consume_header | 最初のヘッダをエンディアンの決定のために利用する |
std::codecvt_mode::generate_header | 最初にヘッダを生成する |
std::codecvt_mode::little_endian | リトルエンディアンとして生成する |
imbue()の引数 | 出力 |
---|---|
imbue()の呼び出しなし | なし |
std::locale("", LC_CTYPE) |
82 A0 (Shift_JISにおける「あ」のコード) |
std::locale(std::locale(), new std::codecvt_utf8<wchar_t>) |
E3 81 82 (UTF-8における「あ」のコード) |
std::locale(std::locale(), new std::codecvt_utf8<wchar_t, 0x10ffff, std::codecvt_mode::generate_header>) |
EF BB BF E3 81 82 (UTF-8におけるBOM+「あ」のコード) |
setbufを呼び出し、バッファのサイズを設定できます。
basic_streambuf<Elem, Tr> *pubsetbuf( char_type *_Buffer, // バッファへのポインタ streamsize _Count // バッファのサイズ );basic_streambuf::pubsetbuf | MSDN
template <class Elem, class Tr = char_traits<Elem>> class basic_filebuf : public basic_streambuf<Elem, Tr>basic_filebuf クラス | MSDN
flags()で書式を設定できます。
fmtflags flags(
fmtflags fmtfl // 新しく設定するフラグ
);
ios_base::flags | MSDN
fmtflに指定できる値はios_base::fmtflagsにあります。
フラグの値 | 作用 |
---|---|
boolalpha | to insert or extract objects of type bool as names (such as true and false) rather than as numeric values. |
dec | to insert or extract integer values in decimal format. |
fixed | to insert floating-point values in fixed-point format (with no exponent field). |
hex | to insert or extract integer values in hexadecimal format. |
internal | to pad to a field width as needed by inserting fill characters at a point internal to a generated numeric field. |
left | to pad to a field width as needed by inserting fill characters at the end of a generated field (left justification). |
oct | to insert or extract integer values in octal format. |
right | to pad to a field width as needed by inserting fill characters at the beginning of a generated field (right justification). |
scientific | to insert floating-point values in scientific format (with an exponent field). |
showbase | to insert a prefix that reveals the base of a generated integer field. |
showpoint | to insert a decimal point unconditionally in a generated floating-point field. |
showpos | to insert a plus sign in a non-negative generated numeric field. |
skipws | to skip leading white space before certain extractions. |
unitbuf | to flush output after each insertion. |
uppercase | to insert uppercase equivalents of lowercase letters in certain insertions. |
フラグを簡単に記述できる、下表の速記もあります。
フラグの値 | 実際の定義 |
---|---|
adjustfield | internal | left | right |
basefield | dec | hex | oct |
floatfield | fixed | scientific |
std::cout.flags(std::ios::dec | std::ios::boolalpha);
このとき指定しなかったフラグは、すべて既定値に初期化されます。よって、
std::cout.flags(std::cout.flags() | std::ios::dec);
のように現在の値と重ねて指定するか、setf()で個別に指定します。この関数では、指定のフラグのみを有効/無効にできます。
fmtflags setf(
fmtflags _Mask // 有効にするフラグ
);
fmtflags setf( fmtflags _Mask, // 有効にするフラグ fmtflags _Unset // 無効にするフラグ );ios_base::setf | MSDN
std::cout << 10 << std::endl; // 10 std::cout.setf(std::ios::hex, std::ios::basefield); std::cout << 10 << std::endl; // a std::cout.setf(std::ios::dec, std::ios::basefield); std::cout << 10 << std::endl; // 10
double n = 1.0 / 6.0; std::cout << n << std::endl; // 0.166667 std::cout.flags(std::ios::fixed); std::cout << n << std::endl; // 0.166667 std::cout.flags(std::ios::scientific); std::cout << n << std::endl; // 1.666667e-01 std::cout.flags(std::ios::floatfield); std::cout << n << std::endl; // 0x1.555555p-3
または、次のようにも指定できます。
std::cout << 10; // 10 std::cout << std::hex << 10; // a std::cout << 10; // a
既定ではテキスト モードで出力され、改行コード (\n) をstd::cout << (char)0xa;
と出力すると、Windows環境では0xd、0xa (\r\n) に変換されて出力されます。これを変換させないようにするには
_setmode(_fileno(stdout), _O_BINARY);
でバイナリ モードとします。 c - What is the simplest way to write to stdout in binary mode? - Stack Overflow _setmode | Microsoft Learn
typedef basic_ios<char, char_traits<char>> ios;