C++ 将文本文件中的数据读入结构数组 [英] C++ Reading data from text file into array of structures

查看:62
本文介绍了C++ 将文本文件中的数据读入结构数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对 C++ 编程相当陌生,并且在将文本文件中的数据读取到结构数组中时遇到了一些问题.我环顾了类似的帖子以尝试找到解决方案,但是,我无法使其中的任何一个对我有用,并想寻求一些帮助.以下是我的数据集示例(P.S. 我将使用多个不同大小的数据集):

I am reasonably new to programming in C++ and i'm having some trouble reading data from a text file into an array of structures. I have looked around similar posts to try and find a solution however, I have been unable to make any of it work for me and wanted to ask for some help. Below is an example of my data set (P.S. I will be using multiple data sets of varying sizes):

00010 0
00011 1
00100 0
00101 1
00110 1
00111 0
01000 0
01001 1

下面是我的代码:

int variables = 5;

typedef struct {
    int variables[variables];
    int classification;
} myData;

//Get the number of rows in the file
int readData(string dataset)
{
    int numLines = 0;
    string line;
    ifstream dataFile(dataset);
    while (getline(dataFile, line))
    {
        ++numLines;
    }
    return numLines;
}

//Store data set into array of data structure
int storeData(string dataset)
{
    int numLines = readData(dataset);

    myData *dataArray = new myData[numLines];

    ...

    return 0;
}

int main()
{
    storeData("dataset.txt");

我想要实现的是将文本文件每行的前 5 个整数存储到 'myData' 结构中的 'variables' 数组中,然后将用空格分隔的最后一个整数存储到 'classification' 中变量,然后将该结构存储到数组 'dataArray' 中,然后移至下一行.

What I am trying to achieve is to store the first 5 integers of each row of the text file into the 'variables' array in the 'myData' structure and then store the last integer separated by white space into the 'classification' variable and then store that structure into the array 'dataArray' and then move onto the next row.

例如,数组中的第一个结构的变量为 [00010],分类为 0.第二个结构的变量为 [00011],分类为 1,以此类推.

For example, the first structure in the array will have the variables [00010] and the classification will be 0. The second will have the variables [00011] and the classification will be 1, and so on.

我真的很感激这方面的帮助,干杯!

I would really appreciate some help with this, cheers!

推荐答案

为您的类型提供流提取和流插入运算符:

Provide stream extraction and stream insertion operators for your type:

#include <cstddef>    // std::size_t
#include <cstdlib>    // EXIT_FAILURE
#include <cctype>     // std::isspace(), std::isdigit()
#include <vector>     // std::vector<>
#include <iterator>   // std::istream_iterator<>, std::ostream_iterator<>
#include <fstream>    // std::ifstream
#include <iostream>   // std::cout, std::cerr, std::cin
#include <algorithm>  // std::copy()

constexpr std::size_t size{ 5 };

struct Data {
    int variables[size];
    int classification;
};

// stream extraction operator
std::istream& operator>>(std::istream &is, Data &data)
{
    Data temp;  // don't write directly to data since extraction might fail
               //  at any point which would leave data in an undefined state.

    int ch;  // signed integer because std::istream::peek() and ...get() return
            //  EOF when they encounter the end of the file which is usually -1.

                                                    // don't feed std::isspace
                                                   //  signed values
    while ((ch = is.peek()) != EOF && std::isspace(static_cast<unsigned>(ch)))
        is.get();  // read and discard whitespace

             // as long as
            //              +- we didn't read all variables
           //               |         +-- the input stream is in good state
          //                |         |      +-- and the character read is not EOF
         //                 |         |      |   
    for (std::size_t i{}; i < size && is && (ch = is.get()) != EOF; ++i)
        if (std::isdigit(static_cast<unsigned>(ch)))
            temp.variables[i] = ch - '0';  // if it is a digit, assign it to our temp
        else is.setstate(std::ios_base::failbit);  // else set the stream to a 
                                                  // failed state which will 
                                                 // cause the loop to end (is)

    if (!(is >> temp.classification))  // if extraction of the integer following the
        return is;                    // variables fails, exit.

    data = temp;  // everything fine, assign temp to data
    return is;
}

// stream insertion operator
std::ostream& operator<<(std::ostream &os, Data const &data)
{
    std::copy(std::begin(data.variables), std::end(data.variables),
              std::ostream_iterator<int>{ os });
    os << ' ' << data.classification;
    return os;

}

int main()
{
    char const *filename{ "test.txt" };
    std::ifstream is{ filename };

    if (!is.is_open()) {
        std::cerr << "Failed to open \"" << filename << "\" for reading :(\n\n";
        return EXIT_FAILURE;
    }

    // read from ifstream
    std::vector<Data> my_data{ std::istream_iterator<Data>{ is },
                               std::istream_iterator<Data>{} };

    // print to ostream
    std::copy(my_data.begin(), my_data.end(),
              std::ostream_iterator<Data>{ std::cout, "\n" });
}

<小时>

取消注释它看起来不那么可怕:


Uncommented it looks less scary:

std::istream& operator>>(std::istream &is, Data &data)
{
    Data temp;
    int ch;

    while ((ch = is.peek()) != EOF && std::isspace(static_cast<unsigned>(ch)))
        is.get();

    for (std::size_t i{}; i < size && is && (ch = is.get()) != EOF; ++i)
        if (std::isdigit(static_cast<unsigned>(ch)))
            temp.variables[i] = ch - '0';
        else is.setstate(std::ios_base::failbit);

    if (!(is >> temp.classification))
        return is;

    data = temp;
    return is;
}

std::ostream& operator<<(std::ostream &os, Data const &data)
{
    std::copy(std::begin(data.variables), std::end(data.variables),
              std::ostream_iterator<int>{ os });
    os << ' ' << data.classification;
    return os;

}

这篇关于C++ 将文本文件中的数据读入结构数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆