Search code examples
c++fstreamiostream

How to read a number from a file and use it as a variable in C++?


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.


Solution

  • 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:

    1. read each line of the file.

    2. 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 ','

    3. converting the returned vector<string> type row-data into appropriate data type and storing in respective column vector col1, col2, col3.

    4. 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.