簡體   English   中英

C++ 將文本文件中的數據讀入結構數組

[英]C++ Reading data from text file into array of structures

我對 C++ 編程相當陌生,並且在將文本文件中的數據讀取到結構數組中時遇到了一些問題。 我環顧了類似的帖子以嘗試找到解決方案,但是,我無法使其中的任何一個對我有用,並想尋求一些幫助。 以下是我的數據集示例(PS 我將使用多個不同大小的數據集):

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”中,然后移動到下一行。

例如,數組中的第一個結構將具有變量 [00010],分類為 0。第二個結構將具有變量 [00011],分類為 1,依此類推。

我真的很感激這方面的幫助,干杯!

為您的類型提供流提取和流插入運算符:

#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" });
}

取消注釋它看起來不那么可怕:

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;

}

看起來您正試圖將二進制值保留為整數索引。 如果是這種情況,它將在內部轉換為整數。 您可能需要再次將 int 轉換為二進制。

如果要按文本文件中的原樣保留數據,則需要為索引值選擇字符/字符串類型。 對於分類,值似乎是 0 或 1。因此您可以選擇 bool 作為數據類型。

#include <iostream>
#include <map>

using namespace std;

std::map<string, bool> myData;

int main()
{
    // THIS IS SAMPLE INSERT. INTRODUCE LOOP FOR INSERT.
    /*00010 0
    00011 1
    00100 0
    00101 1
    00110 1*/
    myData.insert(std::pair<string, bool>("00010", 0));
    myData.insert(std::pair<string, bool>("00011", 1));
    myData.insert(std::pair<string, bool>("00100", 0));
    myData.insert(std::pair<string, bool>("00101", 1));
    myData.insert(std::pair<string, bool>("00110", 1));

    // Display contents
    std::cout << "My Data:\n";
    std::map<string, bool>::iterator it;

    for (it=myData.begin(); it!=myData.end(); ++it)
        std::cout << it->first << " => " << it->second << '\n';

    return 0;
} 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM