Search code examples
c++typestext-filesgetline

Reading In Multiple Data types from a .txt file where one of the strings has spaces C++


I have a text file that looks like this:

Car, CN, 819481, maintenance, false, NONE

Car, SLSF, 46871, business,true, Memphis

Car, AOK, 156, tender, true, San Francisco

(the commas are tabs in actuality, but I was unable to get them to format properly on this site)

I have an object called Car which i am reading the code into and outputting using the output at the bottom of the code. My current code can read in all of the first 5 data types, but I am having trouble with reading in the last column where there can be spaces. I have tried using getline, but to no avail.

Here is the code that I have for the function that takes the txt as inputs

void input()
{
    ifstream inputFile;
    inputFile.open("input.txt",fstream::in);

    if (inputFile.fail())
    {
        cout<<"input failed"<<endl;
        exit(1);
    }

    string type;
    string reportingMark;
    int carNumber;
    string kind;
    bool loaded;
    string destination;

    while(inputFile.peek() != EOF)
    {
        inputFile>>type>>reportingMark>>carNumber>>kind>>loaded;
        while(inputFile.peek() == ' ')
            inputFile.get();
            getline(inputFile, destination);

        Car temp(reportingMark, carNumber, kind, loaded, destination);
        temp.output();
    }

    inputFile.close();
}

Solution

  • Don't use >> operator, use getline:

    string line;
    while (getline(inputFile, line) {
      // split line by tabs or commas
    }
    

    Example split function:

    vector<string> explode(string &str, char separator) {
      vector<string> result;
      string tmp;
    
      for (int i = 0; i < str.size(); i++) {
        if (str[i] == separator) {
          result.push_back(tmp);
          tmp.clear();
        } else tmp += str[i];
      }
    
      if (tmp.size() > 0)
        result.push_back(tmp);
    
      return result;
    }
    

    I hope that std::vector isn't hard for you. Example loading code (instead while(inputFile.peek() != EOF) { ... }):

    string line;
    while (getline(inputFile, line) {
      vector<string> data = split(line, '\t');  // Or use ASCII code 9
      if (data.size() != 5) {
        cout << "Invalid line!" << endl;
        continue;
      }
    
      Car temp(data[0], data[1], stoi(data[2]), data[3], data[4]);
      temp.output();
    }
    

    Don't copy-paste this code, I see that you have bool variables etc. that is not handled.