Cod sursa(job #1349803)

Utilizator cristighrCristi Gherghina cristighr Data 20 februarie 2015 15:00:04
Problema Convertor Scor 0
Compilator c Status done
Runda rosedu_cdl_2015 Marime 3.87 kb
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUFMAX 1024
#define MAXLINES 10128

int main() {
    FILE *fin = fopen("convertor.in", "r");
    FILE *fout = fopen("convertor.out", "a");

    int i = 0, j, x;

    char **key, **value;
    char buffer [BUFMAX];
    char **fields;
    const char sep1[2] = ",";
    const char sep2[2] = ":";
    //tokenComma si tokenDoublePoints
    char  *tokenC, *tokenDP;

    /* Zona de alocare a memoriei necesare */
    fields = malloc(MAXLINES * sizeof(char*));
    key = malloc(MAXLINES * sizeof(char*));
    value = malloc(MAXLINES * sizeof(char*));

    for(i = 0; i < MAXLINES; i++) {
        key[i] = malloc(BUFMAX * sizeof(char));
        value[i] = malloc(BUFMAX * sizeof(char));
        fields[i] = malloc(BUFMAX * sizeof(char));
    }

    /* Citesc pe rand fiecare linie si o despart in functie de virgula */
    while (fgets(buffer, BUFMAX, fin) != NULL) {
        tokenC = strtok(buffer, sep1);
        while(tokenC != NULL)
        {
            /* Dupa ultima virgula de pe linie voi avea doar spatii
             * Ultimul token trebuie luat separat in functie de ']' */
            if(strstr(tokenC, "\n") == NULL || strstr(tokenC, "]") != NULL)
                strcpy(fields[i++], tokenC); // in vector voi face de la j = 0 pana la j <= i (nu strict mai mic) !!!
            tokenC = strtok(NULL, sep1);
        }
    }

    /* Dupa ce am extras fiecare field, de forma cheie : valoare, acum voi pune separat aceste valori */
    for(j = 0; j < i; j++)
    {
        /* Separ acum field-urile dupa ':' */
        tokenDP = strtok(fields[j], sep2);
        /* Fiecare cheie incepe cu ghilimele, si cum nu stiu cate spatii pot avea inainte, caut prima aparitie */
        char *p = strstr(tokenDP, "\"");
        strcpy(key[j], p+1);
        int len = strlen(key[j]);
        /* Incep sa caut de la coada la cap celelalte ghilimele, cand le-am gasit ma opresc si le inlocuiesc cu terminatorul de sir */
        for(x = len - 1; x >= 0; x--)
            if(key[j][x] == '"')
            {
                key[j][x] = '\0';
                break;
            }
        /* De aici incepe al doilea token, adica valoarea */
        tokenDP = strtok(NULL, sep2);
        /* Stiu ca este de 2 feluri, numar intreg sau "sir de caractere" */
        p = strstr(tokenDP, "\"");
        /* Daca este sir de caractere, repet algoritmul ca la chei */
        if(p != NULL)
        {
            strcpy(value[j], p+1);
            len = strlen(value[j]);
            for(x = len - 1; x >= 0; x--)
                if(value[j][x] == '"')
                {
                    value[j][x] = '\0';
                    break;
                }
        }
        /* Daca nu, inseamna ca valoarea este un numar */
        else
        {
            /* Cum nu stiu cate spatii pot avea inainte sau dupa, caut prima cifra sau semn, ceva diferit de spatiu */
            len = strlen(tokenDP);
            for(x = 0; x < len; x++)
                if(tokenDP[x] != ' ')
                    break;
            /* Dupa ce am gasit-o, sar peste acele spatii */
            strcpy(value[j], tokenDP + x);
            /* Caut acum la coada spatiile si le elimin */
            len = strlen(value[j]);
            for(x = 0; x < len; x++)
                if(value[j][x] == ' ')
                {
                    value[j][x] = '\0';
                    break;
                }
        }
    }

    /* Cum cheile se repeta, aflu doar cate distincte sunt */
    for(j = 1; j < i; j++)
        if(strcmp(key[0], key[j]) == 0)
            break;

    /* Acesta este "capul" tabelului */
    for(x = 0; x < j; x++)
        fprintf(fout, "%s,", key[x]);

    for(x = 0; x < i; x++)
    {
        if(x % j == 0)
            fprintf(fout, "\n");
        fprintf(fout, "%s,", value[x]);
    }

    return 0;
}