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.
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.