Code:
#include <vector>
#include <map>
#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
using namespace std;
vector<string> split( const string & s );
class csvreader {
public:
csvreader(const char * fname );
bool write_data( const char * fname, vector<string> & outputorder );
protected:
void make_ordermap (vector<string> & vs );
void read_data( istream & in );
vector<vector<string> > data;
map<string, int> order;
};
vector<string> split( const string & s ) {
stringstream str( s );
vector<string> sv;
string item;
while ( getline( str, item, ';' ) )
sv.push_back( item );
return sv;
}
csvreader::csvreader( const char * fname ) {
ifstream in( fname );
if ( !in )
return;
string header;
getline( in, header );
vector<string> hv = split( header );
make_ordermap( hv );
read_data( in );
}
void csvreader::read_data( istream & in ) {
string line;
while( getline( in, line ) )
data.push_back(split( line ));
}
void csvreader::make_ordermap(vector<string> & vs ) {
int index = 0;
for ( vector<string>::iterator i = vs.begin(); i != vs.end(); ++i, ++index )
order.insert( make_pair( *i, index ));
}
bool csvreader::write_data( const char * fname, vector<string> & outputorder ) {
ofstream out( fname );
if ( ! out )
return false;
vector<string>::size_type len = outputorder.size();
vector<string>::size_type cou = 0;
// create a vector holding the index order for output
vector<int> ov;
for ( vector<string>::iterator i = outputorder.begin(); i != outputorder.end(); ++i ) {
map<string, int>::iterator fi = order.find( *i );
if ( fi != order.end() )
ov.push_back((*fi).second);
else
// field is not available
return false;
}
// write the header
for ( vector<string>::iterator i = outputorder.begin(); i != outputorder.end(); ++i, ++cou ) {
out << *i;
if ( cou < len-1 )
out << ";";
}
out << endl;
// write the data
cou = 0;
for ( vector<vector<string> >::iterator i = data.begin(); i != data.end(); ++ i ) {
vector<string> & dta = *i;
vector<string>::size_type olen = outputorder.size();
for ( vector<string>::size_type ocou = 0; ocou < olen; ++ocou ) {
int idx = ov[ ocou ];
if ( idx >= olen )
return false; // not enough data
out << dta[idx];
if ( ocou < olen -1 )
out << ";";
}
out << endl;
}
return true;
}
int main() {
csvreader reader("data.csv");
/*ID;Data;Tag;Date */
vector<string> output_order;
output_order.push_back("Date");
output_order.push_back("Tag");
output_order.push_back("Data");
output_order.push_back("ID");
if ( ! reader.write_data("new.csv", output_order ) )
cout << "there is something wrong with your data" << endl;
return 0;
}
/*
the input file
ID;Data;Tag;Date
234;15681;345919;91234
156;1924;;134
156;1824;;234
the output file
Date;Tag;Data;ID;
91234;345919;15681;234
134;;1924;156
234;;1824;156
*/
I'm too lazy to explain with words.
Kurt