CocaCola
CocaCola

Reputation: 763

Using getline with CSV

I've spent almost 4 hours trying to get past this issue...

I have a text file with over 100 rows. Each row has 4 values separated by commas. I want to be able to extract each value and save it into a variable (v1...v4).

I have used a for loop, as I won't be reading the entire contents of the file. I'm just trying to get 1 working for now.

So far, I have managed to read a single row. I just need to break the row up now. This is for my Uni assignment, and I am not allowed to use any boost or tokeniser classes. Just getline and other basic commands.

I have this code:

// Read contents from books.txt file
ifstream theFile("fileName.txt");
string v1, v2, v3, v4, line;

for (int i = 0; i < 1; i++) {
    getline(theFile, line, '\n');
    cout << line << endl;  // This part works fine
    getline(line, v1, ",");  // Error here
    cout << v1 << endl;
    getline(line, v2, ",");  // Error here
    cout << v2 << endl;
    getline(line, v3, ",");  // Error here
    cout << v3 << endl;
    getline(line, v4, '\n');  // Error here
    cout << v4 << endl;
}

theFile.close();

The error I get is - error: no matching function for call to ‘getline(std::string&, std::string&, const char [2])

How can I fix this?

Upvotes: 1

Views: 25730

Answers (4)

user1641700
user1641700

Reputation: 53

string filename, text, line;
vector<string> v1; 
vector<string> v2;
vector<string> v3;
vector<string> v4;
int i = 0, k = 0, n;
cout << "Enter filename." << endl;
cin >> filename;
cout << "How many lines of text are in the file?" << endl;
cin >> n;
cin.ignore(200, '\n');
ifstream file(filename.c_str());
if (!file) {
           cerr << "No such file exists." << endl;
           exit(1);
           }
cin.ignore(200, '\n');
if (file.is_open()) {
    while (file.good()) {
           for (k = 0; k < n; k++) { //Loops for as many lines as there are in the file
                for (i = 0; i < 4; i++) { //Loops for each comma-separated word in the line
                              getline(cin, text, ',');
                              if (i == 0)
                                    v1.push_back(text);
                              else if (i == 1)
                                   v2.push_back(text);
                              else if (i == 2)
                                   v3.push_back(text);
                              else if (i == 3)
                                   v4.push_back(text);
                               }
                              }
                          }
                }
file.close();
return 0;
}

Upvotes: 0

Clifford
Clifford

Reputation: 93476

There are two overloads for std::getline:

istream& getline ( istream& is, string& str, char delim );
istream& getline ( istream& is, string& str );

Three of your calls pass a literal string constant as the third parameter, where a single char is required. Use ' rather than " for character constants.

Upvotes: 0

xQuare
xQuare

Reputation: 1323

According to this page, you have to call getline with std::istream as the first parameter.

But line is of type std::string. You should pass a std::istream instead, which can be done by creating an std::istringstream from line. This could work:

string v1, v2, v3, v4, line;
istringstream line_stream;

for (int i = 0; i < 1; i++) {
    getline(theFile, line, '\n');
    cout << line << endl;
    line_stream.str(line); // set the input stream to line
    getline(line_stream, v1, ","); // reads from line_stream and writes to v1
...

If you want to read more about std::istringstream, you can do that here.

Also, according to the above page, the third parameter has to be of type char. But you pass "," which will automatically converted to const char[2], a string. For characters, you use 'c'.

Upvotes: 2

Ben Cottrell
Ben Cottrell

Reputation: 6110

The delimiter for getline is a character. You have used double-quote marks "," which represent a string (hence why the compiler error indicates that you've used char[2] - string literals contain an additional 'nul' character).

Single character values are represented using single quotes instead:

getline(myFile, v1, ',');

edit - I've just noticed you're passing a string as the first parameter, which getline doesn't support (it won't let you retrieve tokens directly from a string). You probably wanted to stuff the string into a stringstream instead

#include <sstream>

// etc ...

std::string csv = "the,cat,sat,on,the,mat";
std::istringstream buffer( csv );
std::string token;

while( std::getline( buffer, token, ',' ) )
{
    std::cout << token << std::endl;
}

Upvotes: 2

Related Questions