Gerdinand
Gerdinand

Reputation: 81

How to read CSV record without the newline CRLF "\r\n"?

im very new to C++ and ive been trying to figure out how to read a CSV file into an vector. So far everything is fine except i dont know how to avoid the newline at the end of every CSV record.

heres my code:

#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>

// stream input operator overloaded to read a list of CSV fields
std::istream &operator >> (std::istream &ins, std::vector<std::string> &record)
{
    record.clear();

    // read the entire line into a string
    std::string line;
    std::getline(ins, line);

    // using a stringstream to separate the fields out of the line
    std::stringstream ss(line);
    std::string field;

    while (std::getline(ss, field, ';'))
    {
        // add the converted field to the end of the record
        record.push_back(field);
    }
    return ins;
}

// stream input operator overloaded to read a list of CSV fields
std::istream &operator >> (std::istream &ins, std::vector<std::vector<std::string>> &data)
{
    data.clear();

    // add results from record into data
    std::vector<std::string> record;

    bool empty;
    while (ins >> record)
    {
        // check if line has a price
        for (unsigned i = 0; i < record.size(); i++)
        {
            std::stringstream ss(record[2]);
            int price;
            if (ss >> price)
            {
                empty = true;
            }
            else
            {
                empty = false;
            }
        }

        if (empty == true)
        {
            data.push_back(record);
        }
    }
    return ins;
}

int main()
{
    // bidemensional vector for storing the menu
    std::vector<std::vector<std::string>> data;

    // reading file into data
    std::ifstream infile("test.csv");
    infile >> data;

    // complain if theres an error
    if (!infile.eof())
    {
        std::cout << "File does not excist." << std::endl;
        return 1;
    }
    infile.close();


    for (unsigned m = 0; m < data.size(); m++)
    {
        for (unsigned n = 0; n < data[m].size(); n++)
        {
            std::string recordQry;
            recordQry += "'" + data[m][n] + "', ";

            std::cout << recordQry;
        }
        std::cout << std::endl;
    }
    return 0;
}

test.csv contains:

CODE;OMSCHRIJVING; PRIJS ;EXTRA;SECTION
A1;Nasi of Bami a la China Garden; 12,00 ;ja;4
A2;Tjap Tjoy a la China Garden; 12,00 ;ja;1
A3;Tja Ka Fu voor twee personen; 22,50 ;ja;1

Upvotes: 3

Views: 3675

Answers (2)

qPCR4vir
qPCR4vir

Reputation: 3571

try:

while (std::getline(ss, field, ';'))
{
    // add the converted field to the end of the record
    record.push_back(field.erase(s.find('\r'));
}
//record.push_back(field.erase(s.find('\r'));
return ins;

Upvotes: 2

ChiefTwoPencils
ChiefTwoPencils

Reputation: 13930

Well I was going to delete my answer but decided to re-submit one since regardless of all the facts flying about getline you do indeed know you're having the issue. In the comments of the other answer I noticed you mentioned that it was originally an excel file. Well, at least in some cases, Microsoft ends their lines with \r\n. Could that be why? getline would still drop the \n but you would still have the carriage return. If that is the case you would need to utilize one of the methods I shared earlier. I hope I've redeemed myself..

I checked writing to a file using \r\n and yes it will leave the \r. I watched it in debug and even when I use getline again to extract the values it leaves it in the string. When it prints to the console it prints the value with the cursor floating underneath the first letter.

Microsoft apparently uses this style for backward compatibility with older machines which required two separate functions - one to return the head to the left margin and one to roll up the paper. Does that sound like the behavior you're experiencing?

Upvotes: 2

Related Questions