プロローグ
ある日、う し た ぷ に き あ く ん 笑はう し た ぷ に き あ 王 国 笑の王様の命令でテキストファイルの内容をすべて読み込んて出力するコードを書きました。
う し た ぷ に き あ く ん 笑
#include <iostream>
#include <fstream>
#include <string>
#include <iterator>
int main() {
std::ifstream ifs{ "u_shi_ta_pu_ni_ki_a_ku_n_lmao.txt" };
std::string s(std::istream_iterator<char>{ ifs }, {}); // ファイルの内容を全部コピーしたつもり
std::cout << s;
}
しかし、実行結果は次のようなものでした。
うしたぷにきあくん笑
空白文字がなくなってしまっています。
このままでは王様が怒ってう し た ぷ に き あ く ん 笑はう し た ぷ に き あ 王 国 笑から追放されてしまうかもしれません。
std::cin >> c
は空白を読み飛ばす
C++の書式化入力( >>
を使った入力)では空白文字が読み飛ばされます。
std::istream_iterator
では >>
が使われるので、空白文字が読み込まれなかったというわけです。
scanf("%c", &c)
では空白文字も読まれるので、う し た ぷ に き あ く ん 笑は勘違いしていたようです。
しかし、非書式化入力関数を使ったコードに書き換えるのは面倒です。
何か楽な方法はないでしょうか?
std::noskipws
マニピュレータ
std::noskipws
は書式化入力で空白文字を読み飛ばさないことを指示するマニピュレータです。
これを使えば、修正は最小限で済みます。
早速さっきのコードを書き換えます。
#include <iostream>
#include <fstream>
#include <string>
#include <iterator>
int main() {
std::ifstream ifs{ "u_shi_ta_pu_ni_ki_a_ku_n_lmao.txt" };
+ ifs >> std::noskipws;
std::string s(std::istream_iterator<char>{ ifs }, {});
std::cout << s;
}
実行してみると次のようになりました。
う し た ぷ に き あ く ん 笑
しっかり空白も含めて出力されています。
これなら、う し た ぷ に き あ く ん 笑は王様に怒られずに済むでしょう。
エピローグ
全角スペースの代わりに半角スペース2個を使っていたので、う し た ぷ に き あ く ん 笑は追放されました。