I'm trying to read a .CSV file and I'm encountering errors with reading strings.
For context, this .CSV file contains a person's name followed by a few personality traits (e.g., likes cats, chocolate, mountains, etc.). I want to read in this data and store it in a map<string, vector<string> > where the person's name is the key and the value is a vector with each personality trait in it.
I'm using the following code, but the moment I uncomment the line stringstream s(line);, I get this error:
libc abi: terminating with uncaught exception of type std::length_error: basic_string
Could anyone tell me what this error means, why I'm getting it, and how to avoid getting it in the future? Any help is appreciated c:
P.S. I've also included the rest of the function commented out so you can see what the finished product is supposed to do. Here's some sample data that I made up:
John,Dog,DC,Beach,Hamburgers,Brownies
Sue,Cat,DC,Beach,Hot Dogs,Brownies
Jim,Dog,Marvel,Mountains,Hot Dogs,Cupcakes
and it should get stored as:
[John] = {Dog, DC, Beach, Hamburgers, Brownies}
[Sue] = {Cat, DC, Beach, Hot Dogs, Brownies}
[Jim] = {Dog, Marvel, Mountains, Hot Dogs, Cupcakes}
//specialized function for reading files
//stores the values in the file in a map with the participant's name as the key and a vector of
//strings as the value
map<string, vector<string> > readFile(fstream & f) {
map<string, vector<string> > output;
//variables for use in splitting the values stored in the .csv
vector<string> row;
string word, line;
//reading the file
while (!f.eof()) {
row.clear();
//reading the next line in the file
getline(f, line);
//removing the trailing newline character
line.pop_back();
//creating new string stream object using line
//stringstream s(line);
/*
//separating the contents of a line by commas and storing them in row
while (getline(s, word, ',')) {
row.push_back(word);
}
//removing the name from the beginning of the vector and storing it in a
//separate variable
string name = row[0];
row.erase(row.begin());
//adding new entry to output
output[name] = row;
*/
}
return output;
}
CodePudding user response:
The problem here is that f.eof() won't return true until getline fails. When getline reads the last line in the file, the getline succeeds, the file is positioned after the last byte, but f.eof is not yet set. Thus, you are calling line.pop_back() on a zero-length string.
Instead, use this idiom:
while( getline(f, line) )
{
row.clear()
...
