【问题标题】:C++ Read in file with only numbers (doubles)C++ 读入只有数字的文件(双打)
【发布时间】:2014-09-09 01:04:08
【问题描述】:

我正在尝试读取一个应该只包含数字的文件。如果它符合该标准,我可以成功读取整个文件,但如果它碰巧有一个字母,我需要返回 false 并带有错误语句。

问题是我发现我的程序在找到这个字符时很难出错。它可以发现它没有问题,但是当它发现时,它决定跳过它。

我要读取文件并尝试仅读取数字的代码:

bool compute::Read (ifstream& stream) 
{
    double value;
    string line;
    int lineNumber = 1;

    if (stream)
    {
        while (getline(stream, line))
        {   
            lineNumber++;
            istringstream strStream(line);

            while (strStream >> value)
            {
                cout << value << endl;
            }

        }

    }

    return true;
}

我使用的输入文件是

70.5 61.2 A8 10.2
2

请注意,我的输入文件中有一个非数字字符。此时它应该会失败并返回 false。

目前,它所做的只是一旦点击“A”,它就会简单地返回下一行,继续 getline while 循环。

对此的任何帮助将不胜感激。

【问题讨论】:

  • 让我们说清楚。该文件不包含doubles,,或者如果包含,您应该以二进制形式读取它。它包含文本格式的实数,您需要将其转换double.
  • 您的代码不包含任何停止和返回 false 的指令...
  • @EJP 它确实包含双精度,它们表示为文本。

标签: c++ file stream double


【解决方案1】:

字符串流确实捕获了这些错误,但是当发现错误时,您没有做任何事情来阻止封闭循环继续。您需要定制您的主循环,以便它在字符串流发现错误时停止,如果字符串流在每次迭代中都被重建,您就无法做到这一点。您应该创建一个for() 循环并在声明部分构造字符串流。并且循环的条件应该是“只要字符串流和stream 没有捕获错误”。例如:

for (std::istringstream iss; iss && std::getline(stream, line);)
{
    iss.clear();
    iss.str(line);

    while (iss >> value)
    {
        std::cout << value << '\n';
    }
}

此外,如果您只想打印每个值,您似乎不需要使用std::getline()std::istringstream。做吧:

while (stream >> value) {
    std::cout << value << '\n';
}

当发现 double 的无效字符时,上述操作将停止。

【讨论】:

  • 感谢您的回复。不过,您评论前半部分的 while 循环似乎从未进入过。我尝试使用它并给它一个只有数字的文件,它只是没有输入它。知道为什么会这样吗?我检查了一下,它确实进入了 for 循环。
  • @Sej 如果仍然无法正常工作,请将iss.clear() 移到iss.str() 行上方。
【解决方案2】:

您需要代码停止流式传输,但如果它尚未到达“输入”的末尾,则返回 false。

一种方法,可能不是最有效但仍然是一种方法,即一次解析一个单词。

如果您首先读入 std::string 并且如果它有效(因此字符串不为空),则从该字符串创建一个 istringstream,或重用现有字符串,然后尝试将其流式传输到 double 值。

如果失败,您的字符无效。

当然,您可以一次从文件中读取一行,然后将其拆分为单词,这样您就可以输出一条有意义的错误消息,显示在哪一行找到了错误的文本。

直接读入双打的问题是流到达文件末尾时会失败。

但是也可以解决这个问题,因为失败的原因有一个您可以检查的错误状态,即您可以检查它是否设置了eofbit。虽然 eofbit 中的 f 代表“文件”,但它适用于任何流,而不仅仅是文件。

虽然这种方法听起来可能比先将单词读入字符串更好,但在正常情况下我更喜欢这种方法,因为您希望能够报告错误,因此您需要在错误中打印所读取的内容。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多