I am trying to write a C++ code to read a text file, each line of the file contains double values, and string values, and there is not specific order for where the double values and the string values appears in the line. an example of how my line looks like:
Inf 1.8 1.4 Inf Inf 3.48.
I am currently using this piece of code:
vector<double>temp;
string line;
ifstream travelFile(filepath);
while (getline(travelFile, line)) {
string delimiter = " ";
size_t pos = 0;
string token;
while ((pos = line.find(delimiter)) != string::npos) {
token = line.substr(0, pos);
if ((token[0] == 'I') || (token[0] == 'i')) { temp.push_back(DBL_MAX); }
else{ temp.push_back(stod(token)); };
line.erase(0, pos + delimiter.length());
}
if (line.size() != 0){
if ((line[0] == 'I') || (line[0] == 'i')) { temp.push_back(DBL_MAX); }
else { temp.push_back(stod(line)); }
travelTime.push_back(temp);
}
temp.clear();
}
However, it has few limitation that I don't like: first it doesn't accept any other delimiter other than the space and sometimes I have to deal with files with tab delimiter. Also it doesn't accept any string value except for "Inf", and some times the files can contain "inf" instead.
There is an easier way to split lines on whitespace: The same way you normally read formatted input from an input stream.
Read the lines as you do now. But instead of using find
and such to parse the string, use an std::istringstream
for the line, and use the normal input operator >>
to extract white-space separated "tokens" from the line.
Something like
while (std::getline(travelFile, line))
{
std::istringstream iss(line);
std::string token;
while (iss >> token)
{
// Do something with the extracted token
}
}
To convert a string to a double
, you can do the same as above, but attempt to read into a double
value and check for success or failure. Or use e.g. std::stod
to convert the string to a double
with validation.