【问题标题】:Using ifstream as fscanf使用 ifstream 作为 fscanf
【发布时间】:2011-01-17 08:28:28
【问题描述】:

假设我有如下输入:

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 轻松做到这一点。我可以得到字符串,然后我可以摆脱非数字并使用字符串流我可以得到两个数字,但这似乎有点麻烦。有没有更简单、更优雅的方法?

谢谢

【问题讨论】:

  • 为什么不像你已经在做的那样使用 scanf 呢?还是你问是因为你想学习?
  • 我问只是因为我想学习 =)
  • 上次我建议在 C++ 程序中使用 C 风格的 IO,SO 上的所有 C++ 精英都对我进行了尝试。

标签: c++ c scanf ifstream


【解决方案1】:
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;
}

查看说明此on ideone here 的完整程序。

我的一篇旧帖子对使用特定字符串做了类似的事情。 (上面的chlit 可以是一个模板,但是chlit&lt;','&gt;() 很难读和写——我宁愿相信编译器)。

【讨论】:

  • 从 3 行到 15 行。 . .我真的很喜欢 C++,但 iostream 有时很难使用。
  • 好吧,如果输入中有意外情况,至少不会导致内存覆盖。
  • @Anders:fscanf 停止扫描意外输入,并返回成功扫描的项目数。
  • @dreamlax: re memory overwrites,问题是很多初学者不保护覆盖字符串缓冲区......你可以使用像“%.20s”或“%.*s”这样的格式“但很多初学者都不会。此外,他们经常尝试在需要%[...] 的地方使用%s
  • @roe: 需要提防的好东西,但没有 - 流式传输到 char 也会跳过空格,除非您事先更改流状态。
【解决方案2】:
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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-19
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    相关资源
    最近更新 更多