Cod sursa(job #1364696)

Utilizator tudor_emil.comantudor emil coman tudor_emil.coman Data 27 februarie 2015 19:42:11
Problema Convertor Scor 0
Compilator c Status done
Runda rosedu_cdl_2015 Marime 6.07 kb
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define BUFFER_SIZE 1024

typedef struct element {
    char *nume;
    struct element *next;
} element;

typedef struct category {
    char *nume;
    element *e;
    struct category *next;
} category;

typedef struct root {
    int category_length;
    category *categorie;
} root;


char *get_sample(FILE *in_file);
root *init();
void generate_categories(root *head, char *buffer);
void add_element(root *head, int here, char *nume);
void completare(root *head, char *buffer);
void afisare(root *head, int level, FILE *out_file);


int main()
{
    FILE *in_file = fopen("convertor.in", "r");
    FILE *out_file = fopen("convertor.out", "w");
    char *buffer;
    int level = 0;

    buffer = get_sample(in_file);
    root *head = init ();
    generate_categories(head, buffer);

    while(buffer != NULL) {
        ++level;
        completare(head, buffer);
        free(buffer);
        buffer = get_sample(in_file);
    }

    afisare(head, level, out_file);

    fclose(out_file);
    fclose(in_file);
    return 0;
}


char *get_sample(FILE *in_file) {
    char *buffer;
    char *buffer2;
    int end;
    int balanced;
    int i;
    int cbs;

    buffer = (char*) malloc (BUFFER_SIZE * sizeof(char));
    buffer2 = NULL;
    cbs = 1;
    end = 0;
    balanced = 0;

    while ( !end ) {
        if (fgets(buffer, BUFFER_SIZE, in_file) == NULL)
            return NULL;
        else {
            for(i = 0; i < strlen(buffer); i++) {
                if(buffer[i] == '}') {
                    balanced = 1;
                    break;
                }
            }
        }
        if (balanced == 1) {
            fseek(in_file, i - strlen(buffer) + 1, SEEK_CUR);
            if(buffer2 != NULL) {
                buffer2 = (char*) realloc(buffer2, cbs * BUFFER_SIZE +
                                          strlen(buffer) + 1);
                strncat(buffer2, buffer, i);
                buffer = buffer2;
            }
            end = 1;
        } else {
            cbs+= strlen (buffer);
            buffer2 = (char*) realloc (buffer2, cbs);
            buffer2[cbs - strlen(buffer) - 1] = 0;
            strcat(buffer2, buffer);
        }
    }
    for ( i = strlen(buffer); i >= 0; i--) {
        if(buffer[i] == '{') {
            buffer = buffer + i;
            break;
        }
    }

    return buffer;
}

root *init() {
    root *head = (root*)malloc(sizeof(root));
    head->category_length = 0;
    head->categorie = NULL;
    return head;
}

void generate_categories(root *head, char *buffer) {
    int j;
    char *pct;
    char *ghi1, *ghi2, *nume;
    int contor;
    category *aux;

    while ((pct = strstr(buffer, ":")) != NULL){
        contor = 0;
        for(j = pct - buffer; j >= 0; j--) {
            if (buffer[j] == '"') {
                contor++;
                if(contor == 1)
                    ghi2 = buffer + j;
                else if(contor == 2)
                    ghi1 = buffer + j;
            }
            if (contor == 2){
                    contor = ghi2 - ghi1 - 1;
                    nume = (char*)calloc((contor + 1), sizeof(char));
                    strncpy(nume, ghi1 + 1, contor);
                    category *cat = (category*)malloc(sizeof(category));
                    cat->nume = nume;
                    cat->e = NULL;
                    cat->next = NULL;
                    head->category_length++;
                    if(head->categorie == NULL)
                        head->categorie = cat;
                    else {
                        aux = head->categorie;
                        while (aux->next)
                            aux = aux->next;
                        aux->next = cat;

                    }
                    break;
            }
        }
        buffer = pct + 1;
    }
}

void add_element(root *head, int here, char *nume) {

    int i;
    category *aux = head->categorie;
    for ( i = 0; i < here; i++)
        aux = aux->next;
    element *el = aux->e;
    element *nou = (element*) malloc(sizeof(element));
    nou->nume = nume;
    nou->next = NULL;

    if (el == NULL) {
        aux->e = nou;
    } else {
        while ( el->next ) {
            el = el->next;
        }
        el->next = nou;
    }
}

void completare(root *head, char *buffer) {
    int i, j, k;
    char *pct;
    char *ghi1, *nume;
    int val;
    int size = strlen(buffer);

    for(i = 0; i < head->category_length; i++) {
        pct = strstr(buffer, ":");
        for(j = 0 ;j < buffer + size - pct; j++) {

            if(pct[j] == '"') {
                ghi1 = pct + j;
                for (k = 1; k < buffer + size - pct; k++) {
                    if(ghi1[k] == '"') {
                        nume = (char*)calloc((k), sizeof(char));
                        strncpy(nume, ghi1 + 1, k - 1);
                        add_element(head, i, nume);
                        break;
                    }
                }
                break;
            } else if (pct[j] >= '0' && pct[j] <= '9' ) {
                sscanf(pct + j, "%d", &val);
                nume = (char*)calloc(10, sizeof(char));
                sprintf(nume, "%d", val);
                add_element(head, i, nume);
                break;
            }
        }
        buffer = pct + 1;
    }
}

void afisare(root *head, int level, FILE *out_file) {
    int i, j, k;
    element *el;
    category *aux = head->categorie;
    for (i = 0; i < head->category_length; i++) {
        fprintf(out_file, "%s,", aux->nume);
        aux = aux->next;
    }
    fprintf(out_file, "\n");
    for (i = 0; i < level; i++) {
        aux = head->categorie;
        for(j = 0; j < head->category_length; j++) {
            el = aux->e;
            for(k = 0; k < i; k++)
                el = el->next;
            fprintf(out_file, "%s,", el->nume);
            aux = aux->next;
        }
        if (i < level - 1)
            fprintf(out_file, "\n");
    }
}