简体   繁体   中英

Reading in a file that has strings and ints in c++

So I have a sample file that I would like to read in, looking something like:

data 1
5
data 2
0
9
6
6
1
data 3
7
3
2

I basically want to assign each of these to variables I have in a struct, eg. my struct looks like:

struct sample_struct

{ int data1; 

double* data2; 

double* data3; 

};

How do I approach this question?

I think I would be able to do it if I had the sample number of integers following each of the string titles, but like this I have no idea. Please help.

You have to solve 2 problems.

  1. Dynamic memory management.
  2. Detect, where, inwhich section we are and where to store the data.

Number 1 will usually be solved with a std::vector in C++. Raw pointers for owened memory or C-Style arrays are not used in C++.

If you do not want to or are not allowed to the a std::vetor you need to handcraft some dynamic array. I made an example for you.

For the 2nd part, we can simple take the alphanumering string as a separator for different sections of the source file. So, if we see an alpha character, we go to a new section and then store the data in the appropriate struct members.

Input and output in C++ is usually done with the extractor >> and inserter << operator. This allows to read from and write to any kind of stream. And, in C++ we use often object oriented programming. Here, data and methods are packed in one class/struct. Only the class/struct should know, how to read and write its data.

Based on the above thoughts, we could come up with the below solution:

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <cctype>

// Ultra simle dynamic array
struct DynamicDoubleArray {

    // Constructor and Destructor
    DynamicDoubleArray() { values = new double[capacity]; }; //  Allocate default memory
    ~DynamicDoubleArray() { delete[] values; };              // Release previously allocated memory

    // Data
    double* values{};                                        // Here we store the values. This is a dynamic array
    int numberOfElements{};                                  // Number of elements currently existing in dynamic array
    int capacity{ 2 };                                       // Number of elements that could be stored in the dynamic array

    void push_back(double v) {                               // Add a new aelement to our dynamic array
        if (numberOfElements >= capacity) {                  // Check, if we have enough capacity to store the new element
            capacity *= 2;                                   // No, we have not. We need more capacity
            double* temp = new double[capacity];             // Get new, bigger memory
            for (int k = 0; k < numberOfElements; ++k)       // Copy old data to new bigger memory
                temp[k] = values[k];
            delete[] values;                                 // Delete old data
            values = temp;                                   // And assign new temp  data to our original pointer
        }
        values[numberOfElements++] = v;                      // Store new data and increment element counter
    }
};

// Our sample struct
struct SampleStruct {

    // Data part
    int data1{};
    DynamicDoubleArray data2{};
    DynamicDoubleArray data3{};

    // Help functions. We overwrite the inserter and extractor operator 

    // Extract elements from whatever stream
    friend std::istream& operator >> (std::istream& is, SampleStruct& s) {
        std::string line{};                                  // Temporaray storage to hold a complete line   
        int section = 0;                                     // Section. Where to store the data
        while (std::getline(is, line)) {
            if (std::isalpha(line[0])) {                     // If we see an alpha character then we are in the next section
                ++section;                                   // Now, we will use the next section
                continue;
            }
            switch (section) {                               // Depending on in which section we are
            case 1:
                s.data1 = std::stoi(line);                   // Section 1 --> Store int data
                break;
            case 2:
                s.data2.push_back(std::stod(line));          // Section 2 --> Add/Store double data 2
                break;
            case 3:
                s.data3.push_back(std::stod(line));          // Section 3 --> Add/Store double data 2
                break;
            default: 
                std::cerr << "\nError: internal mode error\n";
                break;
            }
        }
        return is;
    }
    // Simple output
    friend std::ostream& operator << (std::ostream& os, const SampleStruct& s) {
        os << "\nData 1: " << s.data1 << "\nData 2: ";
        for (int k = 0; k < s.data2.numberOfElements; ++k)
            os << s.data2.values[k] << ' ';
        os << "\nData 3: ";
        for (int k = 0; k < s.data3.numberOfElements; ++k)
            os << s.data2.values[3] << ' ';
        return os;
    }
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM