在c ++中逐行读取文本文件,每行是不同的数据类型?

时间:2017-12-11 11:48:36

标签: c++ visual-studio

问题如下: 给定名为inFile.txt的数据文件(文本文件),其内容为:

2 6 -6 -13 78 34 -1 
2.1 5.6 -8.13 
'A' 'B' 'B' 'A'

将此文件读入名为sums.cpp的C ++程序中,该程序首先计算整数之和,然后计算浮点数之和(数据类型为double),最后将字符连接到字符串“ABBA”。 sums.cpp的输出应存储在输出文件outFile.txt中。

我设法用字符串提取文件的每一行。但是我不知道如何继续使用这些字符串并将它们的值加到三个不同的数据类型变量中。 到目前为止,这是我的代码:

#include <iostream>
#include <cstring>
#include <string>
#include <fstream>

using namespace std;

int main() {
    ifstream fin("inFile.txt");
    ofstream fout("outFile.txt");
    while (!fin.eof()) {

        char line[100];

        while (fin.getline(line, 100)) {

            int i = 0;
            int sumi = 0;
            if ((isdigit(line[i])) && (line[i + 1] == ' ')) {
                int l = strlen(line);
                cout << line << endl;
                for (int i = 0; i < l; i++) {
                    if (isdigit(line[i]) && (line[i + 2] != '-'))
                        sumi += (int)line[i];
                    else if (isdigit(line[i]) && (line[i + 2] == '-'))

1 个答案:

答案 0 :(得分:3)

假设固定文件布局

使用一些c ++ 14善良:

<强> Live On Coliru

#include <iomanip>
#include <iostream>
#include <iterator>
#include <numeric>
#include <sstream>

template <typename T>
T sum_line(std::string const& line) {
    std::istringstream iss(line);
    return std::accumulate(std::istream_iterator<T>(iss), {}, T{});
}

template <>
std::string sum_line<std::string>(std::string const& line) {
    std::istringstream iss(line);

    std::string accum, v;
    while (iss >> std::quoted(v, '\''))
        accum += v;

    return accum;
}

int main() {
    std::string line;
    if (getline(std::cin, line)) std::cout << "First line: " << sum_line<int>(line) << "\n";
    if (getline(std::cin, line)) std::cout << "Second line: " << sum_line<double>(line) << "\n";
    if (getline(std::cin, line)) std::cout << "Third line: " << sum_line<std::string>(line) << "\n";
}

打印

First line: 100
Second line: -0.43
Third line: ABBA

检测每行数据类型

这需要适当的解析器功能。让我们使用Boost Spirit而不是自己动手:

<强> Live On Coliru

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_match.hpp>
#include <numeric>

namespace {
    static auto LineParser() {
        using namespace boost::spirit::qi;

        return copy(skip(blank) [
                hold[
                     *lexeme["'" >> *~char_("'") >> "'"] >> eoi
                   | *int_ >> eoi
                   | *double_ >> eoi
                ]
            ]);
    }

    template <typename... T> using VVector = boost::variant<std::vector<T>...>;
    using LineData = VVector<std::string, int, double>;

    LineData ParseLine(std::string const& line) {
        LineData data;
        boost::spirit::qi::parse(line.begin(), line.end(), LineParser(), data);
        return data;
    }
}

struct Processor {
    using result_type = std::string;

    template <typename... T> 
    auto operator()(boost::variant<T...> const& v) const {
        return boost::apply_visitor(*this, v);
    }

    template <typename T> auto operator()(std::vector<T> const& v) const {
        return std::to_string(std::accumulate(v.begin(), v.end(), T{}));
    }
    auto operator()(std::vector<std::string> const& v) const {
        return std::accumulate(v.begin(), v.end(), std::string{});
    }
};

int main() {
    Processor const process;
    int linenum = 0;

    for (std::string line; getline(std::cin, line);) {
        std::cout << "Processed line #" << ++linenum << ": " << process(ParseLine(line)) << "\n";
    }
}

给出

的输入
'A'
2 6 -6 -13 78 34 -1 

'A' 'B' 'B' 'A'
2.1 5.6 -8.13 

打印

Processed line #1: A
Processed line #2: 100
Processed line #3: 
Processed line #4: ABBA
Processed line #5: -0.430000