0

I'm attempting to read in a file with the following format: 1,2,4,6,8,12,12, . I want to use getline() and a stringstream object to delimit the input and store it into a vector after converting to integer. It works and I can see that by the output being capable of adding with the number one but it still throws the exception after it's done converting all of the numbers in the file.

Output: 2 3 5 7 9 13 13

#include <stdio.h>
#include <string>
#include <iostream>
#include <vector>
#include <fstream>
#include <sstream>
#include <algorithm>
using namespace std;

int main (int argc, char** argv){
    ifstream infile;
    vector <int> vect;
    infile.open("tested");
    if(!infile.is_open()){
        cout<<"File did not open"<<endl;
    }
    else{
        while(!infile.eof()) {
            string line;
            getline(infile, line);
            stringstream ss(line);
            while (ss){
                string p;
                getline(ss, p, ',');
                int x = stoi(p);
                cout<<x+1<<endl;
                vect.push_back(x);
            }
        }
        int i=0;
        while(i<vect.size()){
            int e = vect[i];
            cout<<e<<endl;
            i++;
        }
        sort(vect.begin(), vect.end());
        int j=0;
        while(j<vect.size()){
            int n = vect[j];
            cout<<n<<endl;
            j++;
        }
        cout<<"end reached"<<endl;
    }
}
  • 1
    What happens when `line` is empty after `getline()` ? – Sid S Dec 09 '19 at 05:08
  • 1
    @SidS As I understand it will only call getline once, because it will break out of the while loop because we have reached the end of the file which means the (!infile_.eof()) condition will have been met. –  Dec 09 '19 at 05:11
  • 1
    Do you have any indication that that assumption is right ? Relying on `eof()` is likely to be a major part of your problem. Try checking the return value from `getline()`. – Sid S Dec 09 '19 at 05:13
  • 1
    Also, test `infile`, not `!infile.eof()` – Sid S Dec 09 '19 at 05:15
  • 1
    @SidS I tried infile, it's still throwing the exception and I don't understand what you mean by checking the return value from getline? –  Dec 09 '19 at 05:17
  • @BadMon Loop while `getline()` is true, you are using a delimiter and your last text value has no comma. – ABC Dec 09 '19 at 05:21
  • 1
    @Raymond Your answer worked, I see what you mean. Thanks! –  Dec 09 '19 at 05:34
  • @BadMon, no problem glad I was able to be of some assistance. – ABC Dec 09 '19 at 05:36

2 Answers2

3

Your code is more complex than it needs to be. You don't need to use std::stoi() at all. Since you are already using a std::stringstream, just let it parse the integers for you.

#include <string>
#include <iostream>
#include <vector>
#include <fstream>
#include <sstream>
#include <algorithm>
using namespace std;

int main (){
    ifstream infile("tested");
    if (!infile.is_open()){
        cout << "File did not open" << endl;
    }
    else{
        vector<int> vect;
        string line;
        while (getline(infile, line)) {
            istringstream iss(line);
            int x; char c;
            while (iss >> x) {
                cout << x + 1 << endl;
                vect.push_back(x);
                iss >> c;
            }
        }
        for (size_t i = 0; i < vect.size(); ++i){
            cout << vect[i] << endl;
        }
        sort(vect.begin(), vect.end());
        for (int j = 0; j < vect.size(); ++j){
            cout << vect[j] << endl;
        }
        cout << "end reached" << endl;
    }
    return 0;
}

Live Demo

Remy Lebeau
  • 454,445
  • 28
  • 366
  • 620
1

In regards to my comment, you are using a delimeter with your getline(), so what happens when your last number has no line it throws an exception. Because std::stoi is converting nothing.

So I simply loop while getline() is true.

#include <stdio.h>
#include <string>
#include <iostream>
#include <vector>
#include <fstream>
#include <sstream>
#include <algorithm>

int main (int argc, char **argv)
{
  std::ifstream infile;
  std::vector<int> vect;
  infile.open ("tested", std::ios::in);
  if (!infile.is_open ())
    {
      std::cout << "File did not open" << std::endl;
    }
  else
    {
      std::string p;
      while (!infile.eof ())
        {
          std::string line;
          getline (infile, line);
          std::stringstream ss (line);
          // Changed
          while (getline (ss, p, ','))
            {
              int x = stoi (p);
              // std::cout << x + 1 << std::endl;
              vect.push_back (x);
            }
        }
      int i = 0;
      while (i < vect.size ())
        {
          int e = vect[i];
          std::cout << e << std::endl;
          i++;
        }
      sort (vect.begin (), vect.end ());
      int j = 0;
      while (j < vect.size ())
        {
          int n = vect[j];
          std::cout << n << std::endl;
          j++;
        }
      std::cout << "end reached" << std::endl;
    }
}
ABC
  • 1,805
  • 1
  • 7
  • 17
  • 1
    Why not just replace the while eof loop with while getline? – Alan Birtles Dec 09 '19 at 06:50
  • 2
    [`while (!infile.eof ()) { std::string line; getline (infile, line); ...} ` is wrong](https://stackoverflow.com/questions/5605125/). Use `std::string line; while (getline (infile, line)) { ... }` instead. – Remy Lebeau Dec 09 '19 at 06:52
  • @RemyLebeau Yeah correct, I just wanted to keep it the way he has his code. Usually, when I change things, it starts becoming our work and not theirs. – ABC Dec 10 '19 at 00:38