1

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.

Obsidian
  • 3,719
  • 8
  • 17
  • 30
  • 2
    Does this answer your question? [Read Numeric Data from a Text File in C++](https://stackoverflow.com/questions/14516915/read-numeric-data-from-a-text-file-in-c) – Anton May 25 '21 at 08:34
  • I saw this question before posting but I don't really understand the answers proposed. –  May 25 '21 at 08:38
  • Can you show us your attempt? – Kitswas May 25 '21 at 08:41
  • @PalLaden, I edited my question with an example, I hope it clears things out –  May 25 '21 at 08:48
  • 1
    Please read this carefully: [Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?](https://stackoverflow.com/q/5605125/1968) – Konrad Rudolph May 25 '21 at 08:50
  • @KonradRudolph I will do the changes at the end. Thank you very much for the share. Sadly, it does not really solve my problem here. –  May 25 '21 at 08:53
  • Does this answer your question? [Reading In Multiple Data types from a .txt file where one of the strings has spaces C++](https://stackoverflow.com/questions/28663178/reading-in-multiple-data-types-from-a-txt-file-where-one-of-the-strings-has-spa) – dixit_chandra May 25 '21 at 08:53
  • @dixit_chandra Still not, sorry. I understand the code but I don't see how I can implement it in the same way for my code. –  May 25 '21 at 09:01

1 Answers1

3

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.

dixit_chandra
  • 468
  • 3
  • 14
  • 3
    It probably took you a while to write this out. Why not complete the answer with adequate explanation? I would also remove the first two lines too - you don't often see them in production code. – Bathsheba May 25 '21 at 10:27
  • I've never seen anybody unironically use `not_eq`. Do you *really* think that's more readable than `!=`? – Konrad Rudolph May 25 '21 at 10:35
  • @Bathsheba I am awaiting a confirmation from the post owner whether it is the required solution or not so that I can help with a better explanation. – dixit_chandra May 25 '21 at 10:40
  • @KonradRudolph: It's certainly idiosyncratic but perhaps becoming less so if you come from Python. It certainly puts my head into a "this is not C++" mode. Yes, I find it harder to read fluently. – Bathsheba May 25 '21 at 10:42
  • @dixit_chandra: Stack Overflow has a philosophy consistent with your not necessarily targeting the answer at the OP. It's here to help the wider community. Perhaps therefore the community is asking for a better explanation? – Bathsheba May 25 '21 at 10:43
  • @Bathsheba Python uses `!=`, not `not_eq`. I’m fine with `and`, `or` and `not` (I use them myself), I’m talking specifically about `not_eq`. – Konrad Rudolph May 25 '21 at 10:45
  • not_eq is what preferred in my organization so its due to habit – dixit_chandra May 25 '21 at 10:46
  • @dixit_chandra – Konrad Rudolph May 25 '21 at 10:47
  • @dixit_chandra: We gotta get you another job! – Bathsheba May 25 '21 at 10:56
  • 1
    @Bathsheba sure help me out – dixit_chandra May 25 '21 at 11:00
  • @Bathsheba I recently started contributing to stack-overflow; so I'm not much aware of community guidelines; after your comment, I updated the answer with an explanation of my approach. Thanks for letting me know – dixit_chandra May 25 '21 at 11:24
  • 1
    @dixit_chandra: Thank you. Downvote converted to upvote! – Bathsheba May 25 '21 at 11:29
  • @dixit_chandra Thank you a lot. I'm getting somewhere now. I just have to find a way to implement another data because it is not only posX and posY for everything. Sometimes I have 3 variables. If I follow the same procedure but add col4 for the 3rd variables, would it be initialized at 0 if none is to be find ? –  May 25 '21 at 11:59
  • @Munshine added some logic in the answer which can help you with this problem; however, this logic won't help if you have missing data in columns 1,2 or 3. – dixit_chandra May 25 '21 at 12:15
  • @dixit_chandra I really appreciate your help and time to answer my question. I should be able to do what I want now with the informations you provided me. If I don't, well, shame on me .. Thank you a lot and have a nice day :) –  May 25 '21 at 12:28
  • @Munshine never hesitate in asking even the silliest thing, but before that try by yourself. reach out to the community for further help if needed. – dixit_chandra May 25 '21 at 12:35
  • @dixit_chandra I'm now able to initialize my variables by the code inspired by yours. I can not say how much I appreciate your help. Big thank you, it saved me. Only thing left is to find out why my code is crashing when it come across a blank line or at the end of the file. I will figure it out ! –  May 26 '21 at 15:46