Let's say I have a file I'm reading that goes something like this :
#character posX posY //commentary line: explains what it represents
CharacterName1 50.0 0.0
CharacterName2 32.0 50.0
The goal here is to be able to read the posX et posY and convert them in my C++ program into 2 double variables x and y.
For now, all I'm able to do is to start reading the file and see if the line corresponds to an empty line or a commentary line. Then, if the reading line finds the corresponding character name, i should be able to to continue reading this line to get the posX and the posY, but I have no clue on how to do that. I don't know how to skip the blank and how to start reading the number and how to finish reading it to then convert it into double.
Any idea on how I should do that ?
I truly hope this is clear enough.
Thank you in advance.
Attempt example
void loadMap(std::string const& filepath) {
std::ifstream infile(filepath.c_str());
if(infile.fail()) {
std::cerr << "Error... " << std::endl;
} else { /opening occured correctly
while ( !infile.eof() ) {
std::string line;
std::getline(infile, line);
if ( (line[0] != '#') or (line.empty()) ) { //if line not comment or not empty
if( line.find("CharacterName1") ) {.......
Then I'm lost.
Hope this piece of code will help.
#include <bits/stdc++.h>
using namespace std; //change headers and namespaces; included for ease of use;
vector<string> split(const string &text, const char sep) {
vector<string> tokens;
std::size_t start = 0, end = 0;
while ((end = text.find(sep, start)) not_eq string::npos) {
tokens.emplace_back(text.substr(start, end - start));
start = end + 1;
}
tokens.emplace_back(text.substr(start));
return tokens;
}
int main()
{
ofstream outdata;
outdata.open("example.txt");
if( not outdata ) {
cerr << "Error: file could not be opened" << endl;
exit(1);
}
outdata<<"CharacterName1"<<','<<10.0<<','<<40.0<<endl; //writing data into file
outdata<<"CharacterName2"<<','<<20.0<<','<<30.0<<endl;
outdata<<"CharacterName3"<<','<<30.0<<','<<20.0<<endl;
outdata<<"CharacterName4"<<','<<40.0<<','<<10.0<<endl;
outdata.close();
ifstream inputFile;
inputFile.open("example.txt",fstream::in);
if (inputFile.fail())
{
cerr<<"Error: file could not be opened"<<endl;
exit(1);
}
string line;
vector<string> col1;
vector<double> col2;
vector<double> col3;
while (getline(inputFile, line))
{
if(not line.empty()){
auto lineData = split(line, ','); //separator can change in your case
col1.emplace_back(lineData[0]);
col2.emplace_back(std::stof(lineData[1]));
col3.emplace_back(std::stof(lineData[2]));
}
}
for(int i =0; i<(int) col1.size();i++) //printing the data;
cout<<col1[i]<<"\t"<<col2[i]<<"\t"<<col3[i]<<"\n";
return 0;
}
understand the above logic through the following approach:
read each line of the file.
for each line we will separate the column data through the split(string, sep)
function which will return a vector<string>
containing data of the row. Here sep
is the separator used in the file; as I made input file comma-separated, I used ','
converting the returned vector<string>
type row-data into appropriate data type and storing in respective column vector col1, col2, col3
.
reference of split() functionality.
for another column that may have some missing data you can add some logic like
if(lineData.size() > 3)
col4.emplace_back(std::stof(lineData[3]));
else
col4.emplace_back(0.0);
after col3.emplace_back(std::stof(lineData[2]));
line.