在C 中按行读取文本文件,每行都是不同的数据类型

Read text file line by line in c++ with each line being of different data types?

本文关键字:是不同 数据类型 取文本 读取 文件      更新时间:2023-10-16

问题如下:给定一个名为infile.txt的数据文件(文本文件),其中内容是:

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

将此文件读取到您的C 程序中,称为sums.cpp,该程序首先计算整数的总和,然后将浮点数的总和(数据类型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好处:

活在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而不是滚动我们自己的精神:

活在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