Skip to main content
GameDev.net gamedev.net
🔒 Locked

c++: how to load in a csv file

Started by serratemplar Apr 17, 2007 at 7:42 PM 1 replies 24.5k views
Original Post
serratemplar
serratemplar
comma-seperated values file, in essence each line is of the form: "blah","bleep","bloop",number,number,float,whatever So I open it in an ifstream and think I could load it in thus

ifstream f;
f.open("filename");

while(!f.eof())
{
   f << s1 << s2 << s3 << n1 << n2 << n3 << f1 << w1;

   // do stuff with it
}
However, it's always reading the same line (not advancing through the file) and it's also picking up the commas. So my questions are 1. Can I set a field delimiter some how so that it ignores the commas? (I tried just catching it as a char, but that didn't work; there are no spaces at all between the fields, only commas and newlines.) 2. Why won't it advance? I'm used to using get and getln, so I've never experienced this before. It continually reads the first line in the file... Thanks for your help.
ImperfectFreak
ImperfectFreak
#include

std::string input;
getline(std::cin, input, ',');
nobodynews
nobodynews
Quote:
Original post by ImperfectFreak
#include

std::string input;
getline(std::cin, input, ',');


That's close, but consider this situation:

a, b, c, d
e, f, g, h
i, j, k, l

With your code, d and e are going to be read at the same time. What should probably be done is reading in the entire line and Then use getline, except with stringstreams instead of std::cin. Actually, it should probably be an fstream, not the console. Even more actually it should be an istream, like so:
#include <iostream>#include <string>#include <fstream>#include <sstream>#include <vector>using namespace std;void readCSV(std::istream &input, std::vector< std::vector<std::string> > &output){	std::string csvLine;	// read every line from the stream	while( std::getline(input, csvLine) )	{		std::istringstream csvStream(csvLine);		std::vector<std::string> csvColumn;		std::string csvElement;		// read every element from the line that is seperated by commas		// and put it into the vector or strings		while( std::getline(csvStream, csvElement, ',') )		{			csvColumn.push_back(csvElement);		}				output.push_back(csvColumn);	}}int main(){	std::fstream file("file.csv", ios::in);	if(!file.is_open())	{		std::cout << "File not found!\n";		return 1;	}	// typedef to save typing for the following object	typedef std::vector< std::vector<std::string> > csvVector;	csvVector csvData;	readCSV(file, csvData);	// print out read data to prove reading worked	for(csvVector::iterator i = csvData.begin(); i != csvData.end(); ++i)	{		for(std::vector<std::string>::iterator j = i->begin(); j != i->end(); ++j)		{			std::cout << *j << ", ";		}		std::cout << "\n";	}}


Even even MORE actually, csv is more complex than this. If you put something in quotes, like this( "Hello, World!" ) then it is considered just one element. So you will need to be able to handle quotes as well which my code does not. There's probably nesting stuff that you will need to deal with. Basically, unless you have a simple file, you'll need to put more effort into getting it to work correctly.
C++: A Dialog | C++0x Features: Part1 (lambdas, auto, static_assert) , Part 2 (rvalue references) ,

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.