Cod sursa(job #1358508)

Utilizator RazzinnatorRazvan Brinzea Razzinnator Data 24 februarie 2015 17:30:05
Problema Convertor Scor 100
Compilator cpp Status done
Runda rosedu_cdl_2015 Marime 3.47 kb
#include <iostream>
#include <fstream>
#include <string>
#include <string.h>
#include <vector>
#include <algorithm>

using namespace std;

// Citeste un fisier intreg si stocheaza
// tot continutul sau intr-un string,
// pe care il returneaza ulterior.
string read_data( string filename )
{
    ifstream f( filename.c_str() );
    string s, data;

    while( getline( f, s ) )
    {
        data.append( s );
    }
    f.close();

    return data;
}

// Primeste un string
// care contine date de tip JSON ( in formatul
// specificat in enunt ), si extrage
// un vector de string-uri care contine
// denumirile campurilor din obiectele JSON.
// Returneaza vectorul extras.
vector<string> extract_keys( string data )
{
    bool started_field = false;
    vector<string> keys;
    string key;
    size_t starting_pos;
    size_t found = data.find_first_of( "\"}");

    while( data[found] != '}' )
    {
        if( started_field == false )
        {
            started_field = true;
            starting_pos = found;
        }
        else
        {
            started_field = false;
            key.assign( data, starting_pos + 1, found - starting_pos - 1 );
            keys.push_back( key );
            found = data.find_first_of( ",}", found );
            if( data[found] == '}' )
            {
                break;
            }
        }
        found = data.find_first_of( "\"}", found+1 );
    }

    return keys;
}

vector<string> extract_values( string data, size_t position )
{
    vector<string> values;
    string value;
    size_t starting_pos = data.find_first_of( ":}", position+1 );
    size_t current_pos = starting_pos;
    while( data[current_pos] != '}' )
    {
        while( strchr( "\"0123456789", data[current_pos] ) == 0 )
        {
            current_pos++;
        }

        starting_pos = current_pos;

        if( data[current_pos] == '"' )
        {
            current_pos = data.find( '"' , current_pos+1 );
            value.assign( data, starting_pos+1, current_pos - starting_pos - 1 );
            values.push_back( value );
        }
        else
        {
            while( data[current_pos] >= '0' && data[current_pos] <= '9' )
            {
                current_pos++;
            }
            value.assign( data, starting_pos, current_pos - starting_pos );
            values.push_back( value );
        }
        current_pos = data.find_first_of( ":}", current_pos );
    }

    return values;
}

// Primeste un vector de string-uri
// si il scrie intr-un fisier, in continuarea
// datelor deja existente, in format CSV.
void print_csv_vector( vector<string> line, string filename )
{

    ofstream g;
    g.open( filename.c_str(), ios::out | ios::app );

    for( int i = 0; i < line.size(); i++ )
    {
        g << line[i] << ',';
    }
    g << endl;

    g.close();
}



int main()
{
    string data;
    vector<string> keys;
    vector<string> values;

    // golim fortat continutul fisierului convertor.out
    ofstream g( "convertor.out" );
    g.close();

    data = read_data( "convertor.in" );

    keys = extract_keys( data );

    print_csv_vector( keys, "convertor.out" );

    size_t position = data.find( '{' );
    while( position != string::npos )
    {
        values = extract_values( data, position );
        print_csv_vector( values, "convertor.out" );
        position = data.find( '{', position+1 );
    }

    return 0;
}