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

标签 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++ 程序中,该程序首先计算整数之和,然后计算 float (数据类型 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] == '-'))

最佳答案

假设固定文件布局

使用一些 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

关于c++ - 在 C++ 中逐行读取文本文件,每行具有不同的数据类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47752289/

相关文章:

c++ - 在字符串上使用调整大小

c++ - 解析、词法分析、C++ 内存错误

c++ - MFC 一个父对话框,多个子对话框

c# - WPF 中的多列、可编辑的 TreeView

php - 在 VS 2010 中启用 PHP 亮点?

c++ - Visual C++ 2012 和 PCRE

c++ - 无法从 socket_.async_receive_from 接收数据

c++ - 为什么这个模板函数没有按预期运行?

c++ - 链接 vc6 dll/lib 时未解析的符号

asp.net - IIS 7.0/Visual Studio 2010 - 页面的相关配置数据无效