读取输入文件的各个部分

Big*_*iga 2 c++ file-io parsing

我想用C++读取一个输入文件,其结构(或缺少)就像一系列带有text = number的行,如

input1 = 10
input2 = 4
set1 = 1.2
set2 = 1.e3
Run Code Online (Sandbox Code Playgroud)

我想把这个号码拿出来,把剩下的就扔掉.数字可以是整数或双数,但我知道它们是一个还是其他.

我也想读它

input1 =    10
input2=4
set1   =1.2
set2= 1.e3
Run Code Online (Sandbox Code Playgroud)

以便对用户更加健壮.我认为这意味着它不应该是格式化的红色.

无论如何,有一种聪明的方法吗?

我已经尝试了以下内容,但对我一直在做的事情知之甚少,结果如预期的那样......没有成功.

    #include <stdio.h>
    #include <stdlib.h>
    #include <float.h>
    #include <math.h>
    #include <iostream>
    #include <fstream>
    #include <iomanip>
    #include <cstdlib>
    #include <boost/lexical_cast.hpp>
    #include <string>

    using namespace std;
    using namespace boost;

    int main(){

            string tmp;
            char temp[100];

            int i,j,k;

            ifstream InFile("input.dat");

            //strtol
            InFile.getline(temp,100);
            k=strtol(temp,0,10);
            cout << k << endl;

            //lexical_cast
            InFile.getline(temp,100);
            j = lexical_cast<int>(temp);
            cout << j << endl;

            //Direct read
            InFile >> tmp >> i;
            cout << i << endl;

            return 0;
    }
Run Code Online (Sandbox Code Playgroud)

Mar*_*ork 6

只需一次阅读一行.
然后在'='符号上分割每一行.使用流功能完成剩下的工作.

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

int main()
{
    std::ifstream    data("input.dat");
    std::string      line;

    while(std::getline(data,line))
    {
        std::stringstream    str(line);
        std::string          text;

        std::getline(str,text,'=');

        double   value;
        str >> value;
    }
}
Run Code Online (Sandbox Code Playgroud)

进行错误检查:

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

int main()
{
    std::ifstream    data("input.dat");
    std::string      line;

    while(std::getline(data,line))
    {
        std::stringstream    str(line);
        std::string          text;
        double               value;

        if ((std::getline(str,text,'=')) &&  (str >> value))
        {
            // Happy Days..
            // Do processing.
            continue; // To start next iteration of loop.
        }
        // If we get here. An error occurred.
        // By doing nothing the line will be ignored.
        // Maybe just log an error.
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 好奇的是你选择使用`if continue`而不是`if else`.在教C++时,我试图让学生限制他们对`continue`的使用 - 我发现基于缩进的分支比追踪'break`和`continue`更容易理解. (3认同)

Mat*_*tyT 5

这里已经有一些很好的解决方案.然而,仅仅是为了抛弃它,一些评论意味着Boost Spirit对于这个问题是不恰当的解决方案.我不确定我是否完全不同意.但是,以下解决方案非常简洁,可读(如果您了解EBNF)并且容错.我考虑使用它.

#include <fstream>
#include <string>
#include <boost/spirit.hpp>

using namespace std;
using namespace boost::spirit;

int main()
{
    ifstream       data("input.dat");
    string         line;
    vector<double> numbers;

    while(getline(data,line))
    {
        parse(line.c_str(), 
            *(+~ch_p('=') >> ch_p('=') >> real_p[push_back_a(numbers)]), 
            space_p);
    }
}
Run Code Online (Sandbox Code Playgroud)