Reputation: 175
I have the following code
#include <cstdio>
#include <cmath>
#include <vector>
#include <iostream>
#include <sstream>
#include <string>
int main() {
int NoOfArr;
std::cin >> NoOfArr;
std::vector<std::vector<int>> VecOfVecs;
for(int i = 0; i <= NoOfArr; ++i) {
int x;
// Add all elements
std::vector<int> temp;
std::string str;
std::getline(std::cin, str);
std::istringstream sstr(str);
while(sstr >> x) {
temp.push_back(x);
}
std::cout << "reached2" << std::endl;
temp.erase(temp.begin());
VecOfVecs.push_back(temp);
}
return 0;
}
which is supposed to take an input such as
2
3 1 5 4
5 1 2 3 4 5
The idea is that I want to make a vector of vectors (kind of like a nested list in Python) where the first element in this vector of vectors is the vector {1,5,4} and the second is {1,2,3,4,5}. I don't care about the first digits of the 2nd and 3rd line of the input for now, so I drop them. However, something seems to be going wrong with reading the input, because the while
loop is skipped and the code returns a "Segmentation fault". I'm quite new to the language so I've been unsuccessful in finding what causes this. Any help is appreciated.
Upvotes: 0
Views: 56
Reputation: 5766
Use std::cin.ignore()
before calling the std::getline(std::cin,str)
.
You press enter after typing NoOfArr
and getline reads it as a line(so it considers first line of input in the for loop to be empty line) . It pushes nothing into vector in the first iteration but Then it tries to erase the temp.begin()
. This is giving you segmentation fault.
Using std::cin.ignore()
will skip std::getline(std::cin,str)
from reading the enter key that you press after entering the first input.
This will probably solve your error. I hope this helps.
Upvotes: 2
Reputation: 25388
You need to add std::cin.ignore ();
after std::cin >> NoOfArr;
.
std::cin >> NoOfArr;
does not remove the end-of-line character from the input stream, which means that the next call to getline
returns an empty string. In consequence, vector temp
is empty and so temp.begin()
passes an invalid iterator to temp.erase()
.
The code should test for temp
being empty anyway, since it might be, depending on the input supplied to the program.
Upvotes: 1
Reputation: 11940
I don't care about the first digits of the 2nd and 3rd line of the input for now, so I drop them.
Well, they are there for a purpose after all.
In fact, if you used them and read the stream directly into arrays, rather than first reading a string, you would probably escape this error.
Right now what happens is, you first consume the number of test data, from line 1, and then with getline()
you still read line 1 (its EOL wasn't consumed on reading NoOfArr
). The line comes empty, consequently no numbers are read from it, i.e. your while
loop is 'skipped', and then you try to erase the begin of an empty array...
Upvotes: 2