使用 ifstream 作为 fscanf

发布于 2024-10-12 02:05:04 字数 447 浏览 5 评论 0原文

假设我的输入如下:

N (X_1,Y_1) (X_2,Y_2) .... (X_N, Y_N)

其中 N、X_i 和 Y_i 是整数。

一个例子:

2 (55,1) (521,7)

要阅读本文,我可以这样做(假设所有变量都已定义等):

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

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

谢谢

Assume that I have an input as follows:

N (X_1,Y_1) (X_2,Y_2) .... (X_N, Y_N)

where N, X_i and Y_i are integers.

An example:

2 (55,1) (521,7)

To read this, I can do something like this(assume all variables are defined, etc.):

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

The question is, how can I do this easily using ifstream. I can get string's, and then I can get rid of nondigits and using stringstream I can get two numbers but this seems a bit cumbersome. Is there an easier, more elegant way?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

把时间冻结 2024-10-19 02:05:05
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");

您可以将上面最重要的内部 if 条件简化为...

is >> chlit('(') >> x >> chlit(',') >> y >> chlit(')')

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

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;
}

请参阅说明此 在 ideone 上

我的一篇旧文章对使用特定字符串做了类似的事情。 (上面的 chlit 可以是一个模板,但是 chlit<','>() 读写起来很难看 - 我宁愿相信编译器)。

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");

You can simplify the all-important inner if condition above to...

is >> chlit('(') >> x >> chlit(',') >> y >> chlit(')')

...with a simple support type for consuming a specific character:

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;
}

See a complete program illustrating this on ideone here.

An old post of mine did something similar for consuming specific strings. (The above chlit could be a template, but chlit<','>() is ugly to read and write - I'd rather trust the compiler).

傻比既视感 2024-10-19 02:05:05
cin >> N;
for (int i = 0; i < N; i++)
{
    cin.ignore(100,'(');
    cin >> X[i];
    cin.ignore(100,',');
    cin >> Y[i];
    cin.ignore(100,')');
}

它也可以处理空格,因为它可以读取输入,例如:

2  (  1  ,  3  )    (  5  ,  6  )

ideone 演示: http://www.ideone.com/ hO0xG

cin >> N;
for (int i = 0; i < N; i++)
{
    cin.ignore(100,'(');
    cin >> X[i];
    cin.ignore(100,',');
    cin >> Y[i];
    cin.ignore(100,')');
}

It can handle whitespaces also, as it can read input like:

2  (  1  ,  3  )    (  5  ,  6  )

Demonstration at ideone: http://www.ideone.com/hO0xG

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文