Thread: token text problem

  1. #1
    Registered User
    Join Date
    Feb 2006
    Posts
    71

    token text problem

    I have a file in the following format:

    ID;Data;Tag;Date
    234;15681;345919;91234;...
    156;1924;;134;...
    ...
    ...
    ...

    You see in the first line it define what kind of data the following is.
    The Data is seperated by a ; and if there is no data there are just two ;.

    My problem is now I have an example file lets say (only with this header)

    Data;Tag;Date;ID

    OK I want to read the first file sort it like the example file and write it back to a file. Problem ist the first file can change to e.g.

    Tag;Date;ID;Data

    so the first line (the header) ist variable but must alway get sorted like the example file which is static (the lines after the header also).

    Any ideas how to realize a function which solve this problem?

  2. #2
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    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
    Last edited by ZuK; 06-10-2006 at 07:07 AM.

  3. #3
    Registered User
    Join Date
    Aug 2003
    Posts
    1,218
    And yet a full answer that wont help the op more than a broken finger.....good one
    STL Util a small headers-only library with various utility functions. Mainly for fun but feedback is welcome.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Please Help - Problem with Compilers
    By toonlover in forum C++ Programming
    Replies: 5
    Last Post: 07-23-2005, 10:03 AM
  2. Windows using Dev-C++
    By Renegade in forum C++ Programming
    Replies: 15
    Last Post: 07-07-2005, 08:29 PM
  3. Text string not appearing - RH problem?
    By westm2000 in forum C Programming
    Replies: 1
    Last Post: 10-05-2002, 07:49 PM
  4. Help plz
    By Unregistered in forum C Programming
    Replies: 41
    Last Post: 05-07-2002, 06:23 PM
  5. scrolling text problem
    By Unregistered in forum C++ Programming
    Replies: 3
    Last Post: 03-12-2002, 09:05 PM