I have issues when I try to convert string values extracted from a csv file to double with the functions stod, strtod and atof. I only get the integer part of the values.
I compile with catkin build, which is used to build packages used in ROS. The values I want to convert are the 8 values in the second line in this csv file:
"1","2","3","4","0.0509105","-0.0101653","-0.105985","-0.0534463","Joint Positions"
I extracted them in a vector of string :
Code :
ifstream myfile;
myfile.open(path+robot_state_name+".csv");
string str_value;
getline(myfile, str_value); //The first line will be overwriten
vector<string> positions_str;
cout<<"Positions in string format from csv file : "<<endl;
for(int i = 0; i<=nb_of_variables-1; ++i){
getline(myfile, str_value,',');
positions_str.push_back(str_value);
cout<<i<<" : "<<positions_str[i]<<endl;
}
Console output :
Positions in string format from csv file :
0 : 1
1 : 2
2 : 3
3 : 4
4 : "0.0509105"
5 : "-0.0101653"
6 : "-0.105985"
7 : "-0.0534463"
Then I used std::stod() to convert the data into double. It worked for the 4 first numbers, but then it throws an error. Not that the decimal separator admitted by stod() is the point, as in the csv file.
Code :
cout<<"Position in double format using stod() : "<<endl;
for(int i = 0; i<=nb_of_variables-1; ++i){
cout<<i<<" : "<<stod(positions_str[i])<<endl;
}
Console output :
Position in double format using stod() :
0 : 1
1 : 2
2 : 3
3 : 4
terminate called after throwing an instance of 'std::invalid_argument'
what(): stod
Abandon (core dumped)
It seems that stod() can't take the point... I also tried strtod() and atof(), and I they return 0 for the 4 last values.
But when I type the values myself, it works.
Code :
cout<<"Results of these 3 functions when I type the string values by hand : "<<endl;
positions_str = {"1", "2", "3", "4", "0.0509105", "-0.0101653", "-0.105985", "-0.0534463"};
cout<<"stod() : strtod() : atof() : "<<endl;
char* end_strtod;
for(int i = 0; i<=nb_of_variables-1; ++i){
cout<<stod(positions_str[i])<<" ; "<<strtod(positions_str[i].c_str(), &end)<<" ; "<<atof(positions_str[i].c_str())<<endl;
}
Console output :
Results of these 3 functions when I type the string values by hand :
stod() : strtod() : atof() :
1 ; 1 ; 1
2 ; 2 ; 2
3 ; 3 ; 3
4 ; 4 ; 4
0.0509105 ; 0.0509105 ; 0.0509105
-0.0101653 ; -0.0101653 ; -0.0101653
-0.105985 ; -0.105985 ; -0.105985
-0.0534463 ; -0.0534463 ; -0.0534463
I let there the code I made for strtod and atof, and the function definitions.
Code:
cout<<"Position in double format using strtod() : "<<endl;
char* end;
for(int i = 0; i<=nb_of_variables-1; ++i){
cout<<i<<" : "<<strtod(positions_str[i].c_str(), &end)<<endl;
}
cout<<"Position in double format using atof() : "<<endl;
for(int i = 0; i<=nb_of_variables-1; ++i){
cout<<i<<" : "<<atof(positions_str[i].c_str())<<endl;
}
Console Output :
Position in double format using strtod() :
0 : 1
1 : 2
2 : 3
3 : 4
4 : 0
5 : 0
6 : 0
7 : 0
Position in double format using atof() :
0 : 1
1 : 2
2 : 3
3 : 4
4 : 0
5 : 0
6 : 0
7 : 0
Thanks a lot to those who take some time to answer.
You need to remove "
's from beginning and end of the string before calling std::stod.
Change your conversion code to :
for (auto &s : positions_str)
s.erase(remove(s.begin(), s.end(), '\"'), s.end()); // this will remove double quotes from the string if present
cout << "Position in double format using stod() : " << endl;
for(int i = 0; i < positions_str.size(); ++i)
cout << i << " : " << stod(positions_str[i]) << endl;
Well, you should have posted the content of your csv
file after opening it with a text editor.
The structure is like this:
1,2,3,4,"0.0509105","-0.0101653","-0.105985","-0.0534463","Joint Positions"
The first four columns of being number type and other general or strings.
If the first four had "
's with them, then you won't be getting results for index 0 - 3
.