【问题标题】:C++ Read file with only numbersC++ 读取只有数字的文件
【发布时间】:2014-09-06 00:10:24
【问题描述】:

我正在编写一个读取文件的 c++ 程序。文件应该只包含数字,如果不包含,它只会抛出错误。

我目前可以遍历文件和行并获取每个标记并说明每个标记是什么,但由于我是 c++ 的初学者,我不知道如何只包含数字。

一个示例文件是:

1 2 3 4 5.645 50603 0.543 5.0
100 5.555555 600 1 0 5

               67.64

65.6                                 70

                <spaces>

            90

我尝试了几种方法,并尝试使用空格作为分隔符,但我必须考虑一个空行,分隔符会搞砸。

到目前为止我已经尝试过这些方法:

此方法接受“5.0”,但仅将其打印为“5”: 双i;

while(fin >> i)
{
    cout << " Token value: " << i << endl;
}

此方法不会采用仅包含空格的换行符/换行符:

int i = 0;
int lineNumber = 1;
char token;
const char* const delimeter = " ";
while (fin.good())
{
    // read line into memory with a max length of 10 characters per line
    char buffer[1024];
    fin.getline(buffer, 1024);

    // array to hold the values until compution
    char* token[1024] = {};


    // strtok splits a string into tokens
    // get the first token
    token[0] = strtok(buffer, delimeter);

    // check if the first line is blank (blank is set to 0)
    if (token[0])
    {
        for (i = 1; i < 1024; i++)
        {
            // get more tokens
            token[i] = strtok(0, delimeter);

            // check if there are no more tokens
            if (!token[i])
            {
                break;
            }
        }
    }

    for (int j = 0; j < i; j++)
    {

        // if (token[j] == " ") cout << " this is a space" << endl;
        cout << " Line: " << lineNumber << " --- Token[" << j << "] = " << token[j] << endl;
    }
    cout << endl;
    i++;
    lineNumber++;

}

对 c++ 初学者有什么建议吗(我有 Java 经验)?

编辑:期间角落案例:

如果句点位于最后一行且是唯一字符,则似乎无法识别句点。它不会出错也不会打印出句点:

12 35 67777.75
54433
.

但是,如果是这样,它确实会抛出正确的错误:

12 36 67777.75
.
54433

【问题讨论】:

  • 到目前为止你尝试过什么代码?
  • 添加了到目前为止我尝试过的代码。
  • 是逐行读取文件重要还是只需要一个一个地读取数字?
  • 哪个效率更高。是逐行读取还是逐行读取没有限制,但最终我需要将它们全部计算出来才能计算它们的平均值。
  • 在 C++ 中过滤非数字是否重要?否则,您可能会通过 grep -e "(\d+\s*)+" 'yourfile.txt' &gt; 'yourfile.new.txt' 之类的方式过滤输入文件,只留下用空格分隔的数字。

标签: c++ regex file int double


【解决方案1】:

这可能对你有用。

你可以这样一一读出数字:

int main()
{
    std::ifstream fin("mydatafile.txt");

    // check for errors
    if(!fin.is_open())
    {
        std::cerr << "ERROR: opening input file:" << std::endl;
        return 1; // error code 1
    }

    double d;
    while(fin >> d) // skips spaces and newlines automatically
    {
        // do what you want with the number d here (print it?)
        std::cout << d << '\n';
    }

    // Did we read all the data or was there a problem?
    if(!fin.eof())
    {
        std::cerr << "ERROR: failed to read all the data from input file:" << std::endl;
        return 2; // error code 2
    }

}

while(fin &gt;&gt; d) 非常地道。它确保只有在读取成功时才执行循环体。它考虑了在读取期间发生的错误。

编辑:

添加测试以查看文件是否一直读取到最后

编辑:

作为替代方案,您可以将文本文件中的每个条目读入std::string,然后测试std::string 是否转换为double

#include <fstream>
#include <sstream>
#include <iostream>

int main()
{
    std::ifstream fin("mydatafile.txt");

    // check for errors
    if(!fin.is_open())
    {
        std::cerr << "ERROR: opening input file:" << std::endl;
        return 1; // error code 1
    }

    std::string s;
    while(fin >> s) // skips spaces and newlines automatically
    {
        // now see if we can convert s into a number by
        // turning s into an input stream and read it into a number

        double d;
        if(std::istringstream(s) >> d)
        {
            // do what you want with the number d here (print it?)
            std::cout << d << '\n';
        }
        else
        {
            std::cerr << "ERROR: bad data: \"" << s << "\"" << std::endl;
            // continue? Or not?
        }
    }

    if(!fin.eof())
    {
        std::cerr << "ERROR: failed to read all the data from input file:" << std::endl;
        return 2; // error code 2
    }
}

【讨论】:

  • 您可以使用 for 循环来限制 d 的范围,而不是使用 while 循环,例如 for (double d; fin >> d; ) { /* stuff using d */ }.
  • 这很有帮助,而且有效,除非我使用字母。我需要确保文件只包含数字,所以当我在文件中放入一个字母时,它会到达那个字母,然后就失败了,这是应该的。但是没有办法检查它是否正确失败。 if (stream.fail()) 如果文件找到不是数字的东西,则发生是,但如果流完成然后完成,也会失败,因此在两种情况下都会抛出。 ifstream 是否有任何完成或完成的语句来查看它是否成功解析?
  • @Sej 如果正确读取整个文件,则应设置 eof(文件结尾)标志。您可以使用fin.eof() 进行测试。我将把它添加到示例中。或者,您可以读取字符串而不是数字,并尝试将每个字符串转换为数字。如果其中一个字符串失败,请报告失败并继续或停止您需要的任何一个。
  • 感谢您的回复。我测试的一件事(因为我正在阅读双打)当我提供这样的文件时会发生什么:我编辑了我的帖子以显示极端情况。这会引发一个正确的错误,但似乎有一些极端情况,如果最后一行有句点,那么它不会引发错误,也不会打印出句点。有什么好的方法可以解决这个问题吗?
  • @Sej 我给出的第二个示例应该允许您在发现流浪“。”时继续阅读。在文件中。但如果数据格式不正确,您能做的就只有这么多了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-07
  • 2021-04-26
  • 2017-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多