【问题标题】:What is the modern equivalent (C++) style for the older (C-like) fscanf method?旧的(类似 C 的)fscanf 方法的现代等效(C++)风格是什么?
【发布时间】:2010-03-29 11:32:52
【问题描述】:

如果我想在读取带有分号分隔符的文件时将旧的 C 代码“升级”到新的 C++,最好的选择是什么:

/* reading in from file C-like: */
fscanf(tFile, "%d", &mypost.nr); /*delimiter ; */
fscanf(tFile, " ;%[^;];", mypost.aftername);/* delimiter ; */
fscanf(tFile, " %[^;]", mypost.forename);   /*delimiter ; */
fscanf(tFile, " ;%[^;];", mypost.dept);/*delimiter ; */
fscanf(tFile, " %[^;];", mypost.position);/* delimiter ; */
fscanf(tFile, "%d", &mypost.nr2);

//eqivalent best C++ method achieving the same thing?

【问题讨论】:

  • 我想知道 fscanf 有多严格?如果你在名字所在的那一行读到分号之前的所有字符,下一行怎么能读到分号前的空格? - 此外,fscanf 可能不会那么糟糕,如果您还可以指定在某处读取的最大字符数。

标签: c++ c scanf


【解决方案1】:

您可以为您的结构重载 istream 上的右移运算符,因此:

std::istream& operator>>(std::istream& is, mypost_struct& mps) {
    is >> mps.nr;
    is.ignore(1, ';');
    is.getline(mps.forename, 255, ';');
    is.getline(mps.aftername, 255, ';');
    is >> mps.dept;
    is.ignore(1, ';');
    is >> mps.position;
    is.ignore(1, ';');
    is >> mps.nr2;

    return is;
}

随后,输入就像is >> mypost; 一样简单,其中is 是您打开的文件。

编辑:@UncleBens 感谢您指出这一点,我忘了考虑空格。我已经更新了答案,假设前名和后名可能包含空格。还有一个关于分隔符被双引号引起的相当尴尬的一点......

我刚刚使用结构定义检查了它,如下所示:

struct mypost_struct {
    int nr;
    char forename[255], aftername[255];
    int dept, position, nr2;
};

.. 结果和预期的一样。

【讨论】:

  • 我想知道所有的赞成票是为了什么。提供重载>> 的想法很好,但实现(如何 读取分隔输入)完全被破坏了。 ignore 没有这种形式,即使你修复它也不会改变istream.operator>> 的行为并使用“;”作为分隔符。如果输入也用空格分隔并且没有一个字符串包含一个以上的单词,那么它会有点工作。
【解决方案2】:

正如@susmits 所说,但您也可以将返回的流用作条件,例如:

if (is >> mps.nr && is.ignore(1, ";") && is >> mps.aftername && ...) {
   // all is well ...
} else {
   // bad input format
}

甚至:

if (is >> mps.nr >> ignore(";") >> mps.aftername >> ...) {
    // all is well ...
} else {
    // bad input format
}

【讨论】:

    【解决方案3】:

    如果我想,最好的选择是什么 将旧的 C 代码“升级”到新的 C++...?

    恕我直言,最好的方法是逐行读取文件并使用regular expressions for parsing

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-25
      • 1970-01-01
      • 2018-04-02
      • 1970-01-01
      • 2019-09-01
      相关资源
      最近更新 更多