I have a file like this
2.7388 0 2.4670
3.6384 1 24.5927
8.7844 0 10.6871
11.2892 0 2.6507
19.6054 1 16.8974
25.8811 0 8.0084
For example i'll take the first row 2.7388 0 2.4670
. Im trying to accomplish something like the following
2.7388 = double x
0 = int y
2.4670 = double z
My attempt
struct fileReader{
double x;
int y;
double z;
};
std::vector<fileReader> afileReader(std::string fileName) {
std::vector<fileReader> readtheFile;
std::ifstream List;
std::string line;
List.open(fileName);
char delimiter = ' '; //delimiter added
while (std::getline(List, line))
{
line.pop_back();
std::string token;
std::istringstream ss(line);
fileReader afileReader;
std::getline(ss, token,delimiter);
afileReader.x = std::stod(token); //change from stoi to stod
std::getline(ss, token,delimiter);
afileReader.y = std::stoi(token);
std::getline(ss, token,delimiter);
afileReader.z = std::stod(token); //change from stoi to stod
readtheFile.push_back(std::move(afileReader));
}
for(fileReader x: readtheFile) {
std::cout << x.x;
std::cout << x.y;
std::cout << x.z;
}
return readtheFile;
passengerList.close();
}
When i run this from main running a line afileReader("file.txt")
. I get the following error
terminate called after throwing an instance of 'std::invalid_argument'
what(): stod //error changed
Aborted (core dumped)
Im not sure why im getting an error for stoi as its the correct conversion method to convert the int value to the string(as token is a string)
To refer back to the question though I wish to split the record when a blank space is hit. So refering back to the previous example of 2.7388 0 2.4670
, when 2.7388
is read its assigned to variable x
, when 0
is read its assigned to varible y
and 2.4670
is assigned to variable z
(Recommended) More direct way to do this :
#include <fstream>
#include <iostream>
#include <vector>
struct Data {
double x;
int y;
double z;
};
std::vector<Data> fileReader(std::string fileName) {
std::vector<Data> result;
std::ifstream file(fileName);
Data data;
while (file >> data.x >> data.y >> data.z)
result.push_back(data);
for (auto &&i : result)
std::cout << i.x << ' ' << i.y << ' ' << i.z << '\n';
return result;
}
int main() { fileReader("test.txt"); }
Problems with your original code :
fileReader::x
and fileReader::z
were not floating-type numbers.' '
was not being passed as delimiter in call to std::getline
.line.pop_back()
;afileReader()
(non-void function).Fixed code :
#include <fstream>
#include <iostream>
#include <istream>
#include <sstream>
#include <vector>
struct fileReader {
double x;
int y;
double z;
};
std::vector<fileReader> afileReader(std::string fileName) {
std::vector<fileReader> readtheFile;
std::ifstream List(fileName);
std::string line;
while (std::getline(List, line)) {
std::string token;
std::istringstream ss(line);
fileReader afileReader;
ss >> std::ws;
std::getline(ss, token, ' ');
afileReader.x = std::stod(token);
ss >> std::ws;
std::getline(ss, token, ' ');
afileReader.y = std::stoi(token);
ss >> std::ws;
std::getline(ss, token);
afileReader.z = std::stod(token);
readtheFile.push_back(std::move(afileReader));
}
for (auto &&i : readtheFile)
std::cout << i.x << ' ' << i.y << ' ' << i.z << '\n';
return readtheFile;
}
int main() { afileReader("test.txt"); }