I am trying to write a program that reads some numerical values from a .csv
file, stores them in a std::vector<std::string>
, and then converts these values into double
s and stores them in a std::vector<double>
.
I am trying to do the conversion using stringstream
s, which has worked fine for me in the past.
I have managed to import the numerical values and store them in the std::vector<std::string>
, however I am getting a weird problem when trying to do the conversions to double
. Only the very first value is stored in the std::vector<double>
with a lot of significant figures missing, and the other entries are just ignored and not stored in the std::vector<double>
at all.
Here is my code so far:
#include <string>
#include <fstream>
#include <iostream>
#include <sstream>
#include <vector>
double extract_double(std::string str)
{
std::stringstream ss;
double grade;
//Pass all the course details to string stream
ss << str;
//Extract the double type part of the string stream which is the course grade
ss >> grade;
str = "";
ss.ignore();
return grade;
}
int main()
{
std::ifstream my_input_file;
std::string file_name;
my_input_file.open("scale_free_gamma_2_fitnesses.csv");
int number_of_data_in_file;
std::vector<std::string> fitnesses_string;
std::vector<double> fitnesses;
std::string string_temp;
while (my_input_file.good()) {
//Extract strings from file
std::getline(my_input_file, string_temp, ',');
fitnesses_string.push_back(string_temp);
}
for (auto fitnesses_it = fitnesses_string.begin();
fitnesses_it < fitnesses_string.end(); ++fitnesses_it){
fitnesses.push_back(extract_double(*fitnesses_it));
}
for (auto fitnesses_itt = fitnesses.begin();
fitnesses_itt < fitnesses.end(); ++fitnesses_itt){
std::cout << *fitnesses_itt << std::endl;
}
return 0;
}
You should be reading individual lines from the file first, and then splitting up each line on commas.
And there are easier ways to handle the rest of your code, too.
Try something more like this instead:
#include <string>
#include <fstream>
#include <iostream>
#include <sstream>
#include <vector>
int main()
{
std::ifstream my_input_file("scale_free_gamma_2_fitnesses.csv");
std::vector<std::string> fitnesses_string;
std::vector<double> fitnesses;
std::string line, string_temp;
while (std::getline(my_input_file, line)) {
//Extract strings from line
std:::istringstream iss(line);
while (std::getline(iss, string_temp, ','))
fitnesses_string.push_back(string_temp);
}
for (const auto &s : fitnesses_string){
fitnesses.push_back(std:stod(s));
}
for (auto value : fitnesses){
std::cout << value << std::endl;
}
return 0;
}
In which case, even simpler would be to just get rid of the std::vector<std::string>
altogether:
#include <string>
#include <fstream>
#include <iostream>
#include <sstream>
#include <vector>
int main()
{
std::ifstream my_input_file("scale_free_gamma_2_fitnesses.csv");
std::vector<double> fitnesses;
std::string line, string_temp;
while (std::getline(my_input_file, line)) {
//Extract strings from line
std:::istringstream iss(line);
while (std::getline(iss, string_temp, ','))
fitnesses.push_back(std:stod(string_temp));
}
for (auto value : fitnesses){
std::cout << value << std::endl;
}
return 0;
}