Pj- Pj- - 9 days ago 7
C++ Question

C++ Error when extracting subvector after reading file

I'm reading a file and creating vectors from it, and after that I'm trying to extract a subvector as follows:

vector<double> v = {1, 2, 3, 4, 5};
displayVector(v);
vector<double> v2(&v[1], &v[v.size()]);
displayVector(v2);


In this case the code works and Im just removing the first feature from the original vector, I could also do something like :

v.erase(v.begin());


which also give me the desired output, but for my application is interesting the first way.

The problem here is that Im reading from a file and building the vectors. Such file look like this:

1000025,5,1,1,1,2,1,3,1,1,2
1002945,5,4,4,5,7,10,3,2,1,2
1015425,3,1,1,1,2,2,3,1,1,2
1016277,6,8,8,1,3,4,3,7,1,2
1017023,4,1,1,3,2,1,3,1,1,2
1017122,8,10,10,8,7,10,9,7,1,4
1018099,1,1,1,1,2,10,3,1,1,2
1018561,2,1,2,1,2,1,3,1,1,2
1033078,2,1,1,1,2,1,1,1,5,2
1033078,4,2,1,1,2,1,2,1,1,2
1035283,1,1,1,1,1,1,3,1,1,2
1036172,2,1,1,1,2,1,2,1,1,2
1041801,5,3,3,3,2,3,4,4,1,4
1043999,1,1,1,1,2,3,3,1,1,2
1044572,8,7,5,10,7,9,5,5,4,4
1047630,7,4,6,4,6,1,4,3,1,4
1048672,4,1,1,1,2,1,2,1,1,2
1049815,4,1,1,1,2,1,3,1,1,2
1050670,10,7,7,6,4,10,4,1,2,4
1050718,6,1,1,1,2,1,3,1,1,2
1054590,7,3,2,10,5,10,5,4,4,4
1054593,10,5,5,3,6,7,7,10,1,4
1056784,3,1,1,1,2,1,2,1,1,2


Where the first coordinate is not interesting for me, here is my code:

void displayVector (std::vector<double> &v) {
for (auto &feature : v) {
std::cout << feature << " ";
}
std::cout << std::endl;
}

void displayTrainingSet(vector<FeaturedVector> &data) {
for (auto a : data) {
displayVector(a);
}
}

int main(int argc, char const *argv[]) {

ifstream file;
string filename = "breast-cancer.data";

file.open(filename, std::ifstream::in);

vector<FeaturedVector> data;

while (file.good()) {
string line;
getline(file, line);
istringstream buffer(line);

double feature;
vector<double> v;

while (buffer >> feature) {
if (buffer.peek() == ',') {
buffer.ignore();
}
v.push_back(feature);
}

vector<double> v1(&v[1], &v[v.size()]);
data.push_back(v1);
}

file.close();

//displayTrainingSet(data);
return 0;
}


The code above compiles, but when I try to run it gives me the weird error, which is caused by the line vector v1(&v[1], &v[v.size()]):

libc++abi.dylib: terminating with uncaught exception of type std::length_error: vector
Abort trap: 6


Does someone know why is this happening ? I know that reading from the file and creating the vector v works because I already tried to display the vector on the screen and it works fine. Thanks in advance for the help!

Answer
getline(file, line);

When this code reads the last line of the file, the last character in the file, the final newline, gets read. The code continues from this point, but the file does not have eof set. The eof bit gets set only after an attempt to read from the file fails due to the end of the file.

This hasn't happened yet. getline() only read as far as the last character in the file, the final newline, and stopped.

On the next iteration of the loop:

while (file.good()) {

This will succeed. As I explained, the eof flag is not set yet.

    string line;
    getline(file, line);

This will now fail to read anything from the file, setting the eof bit on the file. line will be an empty string.

Because line is now empty, the inner while loop will not extract anything, and

vector<double> v;

will remain an empty vector.

vector<double> v1(&v[1], &v[v.size()]);

Given that v is now an empty vector, v.size() will be 0, so what do you think is going to happen here, now?

Comments