CSV spreadsheet files are suitable for storing tabular data in a relatively portable way. The CSV format is flexible but somewhat ill-defined. For present purposes, authors may assume that the data fields contain no commas, backslashes, or quotation marks.
The task here is to read a CSV file, change some values and save the changes back to a file. For this task we will use the following CSV file:
C1,C2,C3,C4,C5 1,5,9,13,17 2,6,10,14,18 3,7,11,15,19 4,8,12,16,20
#include <map> #include <vector> #include <iostream> #include <fstream> #include <utility> #include <functional> #include <string> #include <sstream> #include <algorithm> #include <cctype> class CSV { public: CSV(void) : m_nCols( 0 ), m_nRows( 0 ) {} bool open( const char* filename, char delim = ',' ) { std::ifstream file( filename ); clear(); if ( file.is_open() ) { open( file, delim ); return true; } return false; } void open( std::istream& istream, char delim = ',' ) { std::string line; clear(); while ( std::getline( istream, line ) ) { unsigned int nCol = 0; std::istringstream lineStream(line); std::string cell; while( std::getline( lineStream, cell, delim ) ) { m_oData[std::make_pair( nCol, m_nRows )] = trim( cell ); nCol++; } m_nCols = std::max( m_nCols, nCol ); m_nRows++; } } bool save( const char* pFile, char delim = ',' ) { std::ofstream ofile( pFile ); if ( ofile.is_open() ) { save( ofile ); return true; } return false; } void save( std::ostream& ostream, char delim = ',' ) { for ( unsigned int nRow = 0; nRow < m_nRows; nRow++ ) { for ( unsigned int nCol = 0; nCol < m_nCols; nCol++ ) { ostream << trim( m_oData[std::make_pair( nCol, nRow )] ); if ( (nCol+1) < m_nCols ) { ostream << delim; } else { ostream << std::endl; } } } } void clear() { m_oData.clear(); m_nRows = m_nCols = 0; } std::string& operator()( unsigned int nCol, unsigned int nRow ) { m_nCols = std::max( m_nCols, nCol+1 ); m_nRows = std::max( m_nRows, nRow+1 ); return m_oData[std::make_pair(nCol, nRow)]; } inline unsigned int GetRows() { return m_nRows; } inline unsigned int GetCols() { return m_nCols; } private: // trim string for empty spaces in begining and at the end inline std::string &trim(std::string &s) { s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace)))); s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end()); return s; } private: std::map<std::pair<unsigned int, unsigned int>, std::string> m_oData; unsigned int m_nCols; unsigned int m_nRows; }; int main() { CSV oCSV; oCSV.open( "test_in.csv" ); oCSV( 0, 0 ) = "Column0"; oCSV( 1, 1 ) = "100"; oCSV( 2, 2 ) = "200"; oCSV( 3, 3 ) = "300"; oCSV( 4, 4 ) = "400"; oCSV.save( "test_out.csv" ); return 0; }
- Output (in test_out.csv):
Column0,C2,C3,C4,C5 1,100,9,13,17 2,6,200,14,18 3,7,11,300,19 4,8,12,16,400
Content is available under GNU Free Documentation License 1.2.