私が最初の答えを「単純なテイク」と呼んだことに人々が不満を持っていたので、ブースト スピリットを使用した適切なバージョンを次に示します。
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
int main()
{
typedef std::vector<std::vector<double>> data_t;
typedef boost::spirit::istream_iterator It;
std::cin.unsetf(std::ios::skipws);
It first(std::cin), last;
bool ok;
data_t contents;
{
using namespace boost::spirit::qi;
static rule<It, data_t(), blank_type, locals<int>> file;
static rule<It, std::vector<double>(int number), blank_type> row;
_a_type number; // friendly alias
file %= -(omit [int_[number=_1]] > eol > row(number)) % eol;
row = repeat(_r1) [ double_ ];
ok = phrase_parse(first, last, file, blank, contents);
}
if (ok) for (auto& row : contents)
{
std::copy(row.begin(), row.end(), std::ostream_iterator<double>(std::cout," "));
std::cout << "\n";
}
if (first!=last)
std::cout << "Warning: end of file not reached, remaining unparsed: '" << std::string(first, last) << "'\n";
}
明らかにはるかに優れています
- はるかに少ないインクルード行を使用します:)
- コンパイルに約 10 倍の時間がかかり (最適化なし)、最適化を行うとさらに 16% 長くなります。
- それを理解するには、メタプログラミングで約5年間の研究が必要です(冗談ですが、精神のドキュメント/チュートリアルはまったく問題ありません)
深刻な理由: はるかに柔軟です
- より複雑な他の構造要素を解析するように拡張できます
- その場でセマンティクスを実装できます
- NaN と +/-infinity を正しく解析します
- 等
Coliruでのライブ配信もご覧ください