使用C++流读取格式化输入

mat*_*ots 9 c++ iostream

使用时stdio.h,我可以轻松阅读某些格式化的输入,如下所示:

FILE* fin = fopen(...);
fscanf(fin, "x = %d, y = %d", &x, &y);
Run Code Online (Sandbox Code Playgroud)

关于这个伟大的事情是,我真的不担心有多少空间有字符"x"和下面的"=",和其他次要的细节之间.

在C++中,它在我看来好像,

ifstream fin(...);
string s;
fin >> s;
Run Code Online (Sandbox Code Playgroud)

可能会导致s"x""x=",或者甚至"x=12"取决于输入的间距.

是否有一种方便的方法来获得类似于scanf/ fscanfusing iostream/的行为fstream

Moo*_*uck 8

考虑到先决条件,这实际上非常简单.我有这三个功能,我坚持在一个标题的某个地方.这些允许您流入字符文字和字符串文字.我从来都不明白为什么这些不标准.

#include <iostream>

//These are handy bits that go in a header somewhere
template<class e, class t, int N>
std::basic_istream<e,t>& operator>>(std::basic_istream<e,t>& in, const e(&sliteral)[N]) {
        e buffer[N-1] = {}; //get buffer
        in >> buffer[0]; //skips whitespace
        if (N>2)
                in.read(buffer+1, N-2); //read the rest
        if (strncmp(buffer, sliteral, N-1)) //if it failed
                in.setstate(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(0);  //get buffer
        in >> buffer; //read data
        if (buffer != cliteral) //if it failed
                in.setstate(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);
}
Run Code Online (Sandbox Code Playgroud)

鉴于这些,其余的很容易:

in>>'x'>>'='>>data.first>>','>>'y'>>'='>>data.second;
Run Code Online (Sandbox Code Playgroud)

证明在这里

对于更复杂的情况下,你可能想使用std::regexboost::regex,或者一个真正的词法分析器/解析器.