Cod sursa(job #1360839)

Utilizator gabi.cristacheGabi Cristache gabi.cristache Data 25 februarie 2015 18:18:49
Problema Convertor Scor 90
Compilator cpp Status done
Runda rosedu_cdl_2015 Marime 3.79 kb
/************************
@autor Gabriel Cristache
 ************************/

#include <iostream>
#include <string>
#include <fstream>
 
using namespace std;
 
/*returneaza pozitia urmatoarei chei situate pornind
de la pozitia index si -1 in cazul in care o cheie nu a fost gasita*/
int getNextKeyIndex(string line, int index) {
    int i, length = line.length();
 
    for (i = index; i < length && line[i] != '"'; ++i);
 
    if (i >= length)
        return -1;
 
    return i + 1;
}
 
/*returneaza lungimea cheii care porneste de la pozitia index*/
int getKeyLength(string line, int index) {
    int i, length = line.length();
    for (i = index; i < length && line[i] != '"'; ++i);
    return i - index;
}
 
/*returneaza pozitia urmtoarei valori pornind de la pozitia index 
si -1 in cazul in care o valoare nu a fost gasita*/
int getNextValueIndex(string line, int index) {
    int i, length = line.length();
 
    for (i = index; i < length && !(line[i] == '"' || isdigit(line[i])); ++i);
 
    if (i >= length)
        return -1;
 
    if (line[i] == '"') ++i;
    return i;
}
 
/*returneaza lungimea valorii care porneste de la pozitia index*/
int getValueLength(string line, int index) {
    int i, length = line.length();
    bool isNumericalValue = true;
    if (index > 0 && line[index - 1] == '"')
        isNumericalValue = false;
 
    for (i = index; i < length && (isNumericalValue ? isdigit(line[i]) : line[i] != '"'); ++i);
 
    return i - index;
}

int getNextIndex(string line, int index, int type) {
    if (type == 0)
        return getNextKeyIndex(line, index);
    
    return getNextValueIndex(line, index);
}
 
int getLength(string line, int index, int type) {
    if (type == 0)
        return getKeyLength(line, index);
    
    return getValueLength(line, index);
}

/*construieste prima linie din fisierului CSV si returneaza
numarul de coloane din CSV*/ 
int buildCsvHeader(ifstream & fin, ofstream & fout) {
    string line, firstKey;
    int counter = 0;
    bool finished = false;
 
    while (getline(fin, line) && !finished) {
        int index = getNextIndex(line, 0, counter % 2);
 
        while (index != -1) {
            int length = getLength(line, index, counter % 2);
 
            string currentString = line.substr(index, length);
 
            if (counter == 0)
                firstKey = currentString;
            else if (firstKey == currentString) {
                finished = true;
                break;
            }
 
            if (counter % 2 == 0)
                fout << currentString << ",";
 
            ++counter;
            index = getNextIndex(line, index + length + 1, counter % 2);
        }
    }
 
    fout << '\n';
 
    return counter / 2;
}
 
/*construieste continutul fisierului CSV*/
void buildCsvContent(ifstream & fin, ofstream & fout, int elements) {
    int counter = 0;
    string line;
 
    fin.clear();
    fin.seekg(0);
 
    while (getline(fin, line)) {
        int index = getNextIndex(line, 0, counter % 2);
 
        while (index != -1) {
            int length = getLength(line, index, counter % 2);
 
            string currentString = line.substr(index, length);
 
            if (counter % 2 == 1)
                fout << currentString << ",";
 
            ++counter;
            if (counter == 2 * elements) {
                counter = 0;
                fout << '\n';
            }
            index = getNextIndex(line, index + length + 1, counter % 2);
        }
    }
 }
 
int main() {
    ifstream fin ("convertor.in");
    ofstream fout("convertor.out");
 
    int elements = buildCsvHeader(fin, fout);
    if (elements > 0)
        buildCsvContent(fin, fout, elements);
 
    fin.close();
    fout.close();
 
    return 0;
}