- ベストアンサー
C++で特殊な書式付き入力
書式をチェックしつつ入力を行いたい場合があります。 例えば、テキストファイル中の x=100 という行から数値部分を読み込みたいとき、 FILE *f = fopen(filename); int x; fscanf(f, "x=%n", &x); としてfscanfの戻り値をチェックすれば、入力が正しいフォーマットであることを チェックしつつ読み込むことができます。 同様のことをC++のストリームクラス(istream)を使って行う手段はないのでしょうか?
- みんなの回答 (7)
- 専門家の回答
質問者が選んだベストアンサー
C++のiosteramには、Cのストリームのような書式付入出力(print/scan)はないです。 自分で書式に応じた読み出し処理を定義してください。 なお、次期C++ではregex(正規表現)が増えるはずで、 C時代のfscanfはC++風に拡張するとこうなるってことなんじゃないでしょうか。 逆に言うと現時点ではまだ次期仕様はTRしかないので、 それらやboost::regex、boost::tokenizer等を使うか、 言語標準に固執するならお手軽さはstd::fscanfでしょうか。 > 必ずしもCのprintf, scanfファミリーの機能全てを > 上位言語であるC++のストリームクラスが > サポートしているわけではないことが幾分意外だった > ということです。(事実ならば) C++はCの完全上位互換ではありませんし、 むしろscanfとかは「互換性を捨てたかった」ようにも思えますけど。 必要な人はC++でもstd::scanfがそのまま使えるわけで、 実際、C++ではCにあったいくつかの融通などを捨ててます。
その他の回答 (6)
- MrBan
- ベストアンサー率53% (331/615)
> std::ostreamほうにはostream &form(char *format)というprintfと同等の機能が残してあるだけに、 既に書かれてますが、標準C++の言語仕様にはないです、それ。 GCCなどの独自拡張で、しかもとっくにobsoleteされてます。 類似ならboost::formatとかの方がまだよいかと。 # クラス化してオペレータ定義するかマニピュレータ書くのが正道かなぁ。
お礼
御指摘の通り、上記関数があったのは少々特殊な環境でした。 返信が遅れてすみません。コメントありがとうございました。
- jacta
- ベストアンサー率26% (845/3158)
> std::ostreamほうにはostream &form(char *format)というprintfと同等の機能が残してあるだけに、istreamにもフォーマット指定メソッドが欲しかったです。 それは、EGCSとかの相当古い実装の話ではないでしょうか? そうであれば、istream::scanもあった気がします。 いずれにしても、使うべきではない関数だと思います。
お礼
御指摘のとおり、上記関数があったのはちょっと特殊な環境でした。 返信が遅れてすみません。ありがとうございました。
- koko_u_
- ベストアンサー率18% (459/2509)
>std::ostreamほうにはostream &form(char *format)というprintfと同等の機能が残してあるだけに そんなんあったっけ? VC2005 には見当らないんだけど、探し方が悪いんか?
- MrBan
- ベストアンサー率53% (331/615)
# 補足 C++の言語設計者自身の本を読んでいると(「プログラミング言語C++」とか)、 printf/scanfなどは可変長引数でコンパイラが正しく引数の 方チェックをできないのがイケテナイ、という持論が読み取れるように思います。
補足
ええ、それは十分理解できます。 それゆえに上記のような柔軟な読み込みができなくなったのはちょっと痛いですね。 std::ostreamほうにはostream &form(char *format)というprintfと同等の機能が残してあるだけに、istreamにもフォーマット指定メソッドが欲しかったです。
- koko_u_
- ベストアンサー率18% (459/2509)
>だとすると、C++でもprintfファミリーと手が切れませんね。 いやいや、そこはもっとマシな実装をしようよ。
補足
あ、いえ、printfファミリーを使って実装するという意味ではないです。 必ずしもCのprintf, scanfファミリーの機能全てを上位言語であるC++のストリームクラスがサポートしているわけではないことが幾分意外だったということです。(事実ならば)
- koko_u_
- ベストアンサー率18% (459/2509)
自前で operator>>() をオーバーロードするとかではダメ?
補足
自分で実装しないかぎりストリームクラスにそのような機能はないということでしょうか。 だとすると、C++でもprintfファミリーと手が切れませんね。 補足ですが、上の%nは%dの間違いです。
お礼
ご回答ありがとうございます。 大変参考になりました。そういえばboostを使う手がありましたね。