使用ifstream作为fscanf

kol*_*vra 9 c c++ scanf ifstream

假设我输入如下:

N (X_1,Y_1) (X_2,Y_2) .... (X_N, Y_N)
Run Code Online (Sandbox Code Playgroud)

其中N,X_i和Y_i是整数.

一个例子:

2 (55,1) (521,7)
Run Code Online (Sandbox Code Playgroud)

要读这个,我可以做这样的事情(假设所有变量都是定义的,等等):

fscanf(fin,"%d ",&N);
for (int i = 0; i < N; i++)
   fscanf(fin,"(%d,%d) ", &X[i], &Y[i]);
Run Code Online (Sandbox Code Playgroud)

问题是,如何使用ifstream轻松完成此操作.我可以得到字符串,然后我可以摆脱nondigits并使用stringstream我可以得到两个数字,但这似乎有点麻烦.有更简单,更优雅的方式吗?

谢谢

Ton*_*roy 6

int n, x, y;
char c;
if (is >> n)
    for (int i = 0; i < n; ++i)
        if (is >> c && c == '(' &&
            is >> x &&
            is >> c && c == ',' &&
            is >> y &&
            is >> c && c == ')')
        {
            X[i] = x;
            Y[i] = y;
        }
        else
            throw std::runtime_error("invalid inputs");
Run Code Online (Sandbox Code Playgroud)

你可以简化if上面所有重要的内在条件......

is >> chlit('(') >> x >> chlit(',') >> y >> chlit(')')
Run Code Online (Sandbox Code Playgroud)

...使用简单的支持类型来消费特定字符:

struct chlit
{
    chlit(char c) : c_(c) { }
    char c_;
};

inline std::istream& operator>>(std::istream& is, chlit x)
{
    char c;
    if (is >> c && c != x.c_)
        is.setstate(std::iostream::failbit);
    return is;
}
Run Code Online (Sandbox Code Playgroud)

在这里查看完整的程序,在ideone上进行说明.

我的一个旧帖子做了类似的消费特定字符串.(上面chlit可能是一个模板,但chlit<','>()读取和写入都很难看 - 我宁愿相信编译器).