Cod sursa(job #1365986)

Utilizator tudor_emil.comantudor emil coman tudor_emil.coman Data 28 februarie 2015 17:29:40
Problema Convertor Scor 90
Compilator c Status done
Runda rosedu_cdl_2015 Marime 6.14 kb
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>

#define BUFFER_SIZE 4096

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_content(int );
char *get_sample(char*);
root *init();
void generate_categories(root *, char *);
void add_element(root *, int here, char *nume);
void completare(root *, char *);
void afisare(root *, int , FILE *);


int main()
{
    int in_file = open("convertor.in", O_RDONLY);
    FILE *out_file = fopen("convertor.out", "w");
    char *everything;
    char *sample;
    int level = 0;

    everything = get_content(in_file);
    sample = get_sample(everything);

    root *head = init ();
    generate_categories(head, sample);

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

    afisare(head, level, out_file);

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


char *get_content(int in_file) {
    char *buffer;
    int end;
    int cbs;
    int bytes_read;

    buffer = (char*)malloc(BUFFER_SIZE * sizeof(char));
    end = 0;
    cbs = 0;
    bytes_read = 0;

    while (!end) {
        bytes_read = read(in_file, buffer + cbs, BUFFER_SIZE);
        if(bytes_read < BUFFER_SIZE) {
            end = 1;
        } else {
            cbs += BUFFER_SIZE;
            buffer = (char*)realloc(buffer, cbs + BUFFER_SIZE);
        }
    }

    buffer[cbs+bytes_read - 1] = 0;
    return buffer;
}

char *get_sample(char *everything) {
    static int offset = 0;
    char *current = everything + offset;
    char *buffer;
    char *ptr1, *ptr2;
    int size;
    int i;
    int balanced;

    ptr1 = NULL;
    balanced = 0;
    for(i = 0; i < strlen(current); i++) {
        if (current[i] == '}' && balanced == 1){
            ptr2 = current + i;
            break;
        }

        if(current[i] == '{') {
            ptr1 = current + i;
            balanced = 1;
        }
    }

    if (ptr1 == NULL)
        return NULL;
    ptr1++;
    size = ptr2 - ptr1 + 1;
    buffer = (char*) malloc(sizeof(char) * size);
    for(i = 0; i < size; i++) {
        buffer[i] = ptr1[i];
    }
    buffer[size - 1] = 0;

    offset += ptr2 - current + 1;

    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");
    }
}