にフォームの近くでの解析ルールを記述することができ、私は、文字列と文字リテラルで読むことができるコードのビットを書いたということです。通常のストリーム読み込みと同様に、無効なデータを取得した場合、ストリームのバッドビットを設定します。これは、ワイドストリームを含むすべてのタイプのストリームに有効です。新しいヘッダーで、このビットをスティック:
#include <iostream>
#include <string>
#include <array>
#include <cstring>
template<class e, class t, int N>
std::basic_istream<e,t>& operator>>(std::basic_istream<e,t>& in, const e(&sliteral)[N]) {
std::array<e, N-1> buffer; //get buffer
in >> buffer[0]; //skips whitespace
if (N>2)
in.read(&buffer[1], N-2); //read the rest
if (strncmp(&buffer[0], sliteral, N-1)) //if it failed
in.setstate(in.rdstate() | std::ios::failbit); //set the state
return in;
}
template<class e, class t>
std::basic_istream<e,t>& operator>>(std::basic_istream<e,t>& in, const e& cliteral) {
e buffer; //get buffer
in >> buffer; //read data
if (buffer != cliteral) //if it failed
in.setstate(in.rdstate() | std::ios::failbit); //set the state
return in;
}
//redirect mutable char arrays to their normal function
template<class e, class t, int N>
std::basic_istream<e,t>& operator>>(std::basic_istream<e,t>& in, e(&carray)[N]) {
return std::operator>>(in, carray);
}
そしてそれは、入力された文字が非常に簡単になります。
std::istringstream input;
double val1, val2;
if (input >>'('>>val1>>','>>val2>>')') //less chars than scanf I think
{
// got them!
}
PROOF OF CONCEPT。今すぐcin
の文字列と文字リテラルを入力できます。入力が完全一致でない場合は、正しく入力できなかった他のタイプと同じように動作します。これは、最初の文字ではない文字列リテラルの空白にのみ一致することに注意してください。唯一の4つの機能は、すべて脳死の単純な機能です。
EDIT
ストリームを解析することは悪い考えです。正規表現を使用してください。
こんにちは、私は本当にブーストが何かを持っていると思います。今では私の指はそれのために私自身のライブラリを作るのがかゆいです... –
FWIW、私は何か他のものと同じように "C++"と思っています - それは能力に限界があります(iostreamsほど構文的にはひどいものではありません)。私はvariadicテンプレートの観点からCのフォーマット関数を実装する提案を見てきました(したがって、C++ 11のみ)。それは演奏することができれば、これは大きな改善となるでしょう。良い小さなプロジェクト - 完了したら教えてください。 ; ^) – mcmcc
@mcmcc:実際には、バリデーショナルテンプレートを使って 'printf'を実装するのは、位置引数を除けばかなり簡単です。私は 'sscanf'と同じ問題を期待します。それとは別に、パフォーマンスに問題は見られません。何かがあれば、部分的なインライン展開が本当に有益なことがあります。 –