Reputation: 81
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
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
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