0

I need to read from CSV: ISBN,title,author,genre,year published and I used Mockaroo.com to generate it. Second line looks like this:

289244243-5,"Eye of Vichy`,` The (Oeil de Vichy, L')",Nels Janoschek,Documentary,1943

and as you can see that highlighted comma is the problem because my function reads up to comma and sets values:

while(getline(excel_file, word, ',')){
        book.set_isbn(word);
        getline(excel_file, word, ',');
        book.set_title(word);
        getline(excel_file, word, ',');
        book.set_author(word);
        getline(excel_file, word, ',');
        book.set_genre(word);
        getline(excel_file, word, '\n');
        book.set_year_published(word);
}

I noticed that those commas that shouldn't be included have space after , , meanwhile commas that should cause stoppage of getline() are followed by letter.

So I want to know if there is some way to exclude , (comma space) to cause getline() to stop reading?

Alan Birtles
  • 32,622
  • 4
  • 31
  • 60
qu4lizz
  • 317
  • 2
  • 12
  • You need to write a proper csv parser or download a library. You need to pay attention to the quotes surrounding the strings – Alan Birtles Nov 21 '21 at 22:37

1 Answers1

0

The title is in double quotes, probably only because it contains a comma. To fix, you'll have to read line by line from the file, and then split the resulting string, so you can add the necessary logic.

For example:

// Splits a CSV line and returrns individual components in a array.
std::vector<std::string> splitCSV(const std::string& str)
{
    std::vector<std::string> result;
    size_t pos1 = 0;
    size_t pos2 = 0;
    
    for (;;)
    {
        if (str[pos1] == '\"')
        {
            // find closing quote.
            pos2 = str.find('\"', pos1 + 1);
            if (pos2 == std::string::npos)
            {
                 // syntax error!!!!  
                 // throwing an exception may be a good idea here.
                 return {};
            }
            result.push_back(str.substr(pos1 + 1, (pos2 - pos1) - 2));
            pos2 = str.find(',', pos2 + 1);
        }
        else
        {
            pos2 = str.find(',', pos2 + 1);

            if (pos2 != std::string::npos)
                result.push_back(str.substr(pos1, (pos2 - pos1) - 1));
            else
                result.push_back(str.substr(pos1);
        }

        if (pos2 == std::string::npos)
            break;
        pos1 = pos2 + 1;
   }
   return result;        
}


int main()
{
    // ...
    std::string line;
    while (getline(excel_file, line))
    {
        auto rec = splitCSV(line);
        if (rec.size() >= 5)
        {
            book.set_isbn(rec[0]);
            book.set_title(rec[1]);
            book.set_author(rec[2]);
            book.set_genre(rec[3]);
            book.set_year_published(rec[4]);
        }
        else
        {
            // provide user with error message
        }
    }
}

NOTE: this code is for illustration purposes. I have not tried to compile it, but it should be fairly close to what you have to do to get the functionality you need.

Michaël Roy
  • 6,338
  • 1
  • 15
  • 19
  • you should probably at least check that the comma immediately follows the quote. Most CSV dialects also have some way of embedding quotes inside quoted strings which this code doesn't handle – Alan Birtles Nov 22 '21 at 07:56