Pagini recente » Cod sursa (job #2361020) | Cod sursa (job #2284720) | Cod sursa (job #1854418) | Cod sursa (job #2971140) | Cod sursa (job #1346383)
/*
* Fisierul in format JSON este un vector cu elemente hash-uri.
* Fiecare hash este format din perechi cheie:valoare.
*
* Parsez fiecare linie caracter cu caracter si stochez caracterele pe care le
* intalnesc fie in stringul cu chei, fie in cel cu valori in functie de
* caracterele delimitatoare intalnite pana atunci.
*
* La sfarsitul fiecarui hash scriu cele doua stringuri in fisier.
*/
#include <stdio.h>
#include <ctype.h>
#define LG_MAX 9025 /* lungime maxima linie; 1024 + '\0' */
#define MAX_LINII 20128 /* numarul maxim de linii in fisier */
#define SEP_CV ':' /* separa cheia de valoare */
#define SEP_EL ',' /* separa elementele hash-ului */
#define START_DATE '[' /* inceputul datelor de citit */
#define STOP_DATE ']' /* sfarsitul datelor de citit */
#define START_HASH '{' /* semnaleaza inceputul unui hash */
#define STOP_HASH '}' /* semnaleaza sfarsitul unui hash */
/* Masturbare intelectuala */
#undef END_OF_LINE
#define END_OF_LINE(a) (((a) == EOF || (a) == '\n' || (a) == '\0') ? 1 : 0)
#undef EROARE
#define EROARE(c, s) do { \
fprintf(stderr, "\nEROARE - %s\n\n", (s));\
return (c); \
} while(0)
/* Sterge blankurile dintre valori si ghilimele */
char *jstrip(char *s);
/* Scrie datele in fisier, returneaza 0 in caz de eroare */
int flush_data(FILE *f, char *s);
/* Initializeaza stringurile folosite la citirea datelor */
void init_data(char *s, int *length);
struct flag {
unsigned short citit_antet;
unsigned short in_hash;
unsigned short in_date;
unsigned short in_valoare;
};
int main(void)
{
FILE *in, *out;
char buflin[LG_MAX]; /* buffer citire linia curenta */
char antet[LG_MAX]; /* antetul cu cheile */
char valori[LG_MAX]; /* valorile de scris */
unsigned short nr_linii; /* numarul de linii citite */
struct flag flags = {0};
int i_antet, i_valori; /* index antet si valori */
int i;
if ((in = fopen("convertor.in", "r")) == NULL)
EROARE(1, "Fisierul convertor.in nu a putut fi deschis");
if ((out = fopen("convertor.out", "w")) == NULL)
EROARE(2, "Fisierul convertor.out nu a putut fi scris");
nr_linii = 0;
while (fgets(buflin, LG_MAX, in) != NULL) {
if (++nr_linii > MAX_LINII)
EROARE(3, "S-a depasit numarul maxim de linii");
for (i = 0; !(END_OF_LINE(buflin[i])); i++) {
if (flags.in_date) {
if (buflin[i] == STOP_DATE) {
return 0;
flags.in_date = 0;
} else if (flags.in_hash) {
if (buflin[i] == STOP_HASH) {
if (flags.citit_antet == 0) {
antet[i_antet] = '\0';
jstrip(antet);
flush_data(out, antet);
flags.citit_antet = 1;
}
valori[i_valori++] = ',';
valori[i_valori] = '\0';
jstrip(valori);
flush_data(out, valori);
flags.in_hash = 0;
flags.in_valoare = 0;
/* Sunt in interiorul unei valori */
} else if (flags.in_valoare) {
if (buflin[i] != SEP_EL)
valori[i_valori++] = buflin[i];
else {
valori[i_valori++] = ',';
flags.in_valoare = 0;
}
/* Am terminat de citit cheia */
} else if (buflin[i] == SEP_CV) {
if (flags.citit_antet == 0)
antet[i_antet++] = ',';
flags.in_valoare = 1;
/* Citesc o cheie */
} else if (flags.citit_antet == 0) {
antet[i_antet++] = buflin[i];
}
/* Iterez pana gasesc un nou hash */
} else if (buflin[i] == START_HASH) {
init_data(antet, &i_antet);
init_data(valori, &i_valori);
flags.in_hash = 1;
}
/* Iterez pana gasesc inceputul unui hash */
} else if (buflin[i] == START_DATE) {
flags.in_date = 1;
}
}
}
EROARE(5, "Date JSON incomplete sau inexistente");
}
/* Sterge blankurile dintre valori si ghilimele */
char *jstrip(char *s)
{
int i, j;
if (s == NULL)
return NULL;
j = 0;
i = 0;
while (s[i] != '\0') {
/* Sterg blankurile de inceput */
for (; isblank(s[i]); i++)
;
if (s[i] == '"') {
++i;
while (s[i] != '"')
s[j++] = s[i++];
/* Sterg blankurile dupa ghilimele */
for (; s[i] != ','; i++)
;
} else {
while (s[i] != ',')
s[j++] = s[i++];
}
/* Copiez si virgula */
s[j++] = s[i++];
}
s[j] = '\0';
return s;
}
/* Scrie datele in fisier, returneaza 0 in caz de eroare */
int flush_data(FILE *f, char *s)
{
if (s == NULL)
return 0;
if (fprintf(f, "%s\n", s) == 0)
return 0;
return 1;
}
/* Initializeaza stringurile folosite la citirea datelor */
void init_data(char *s, int *length)
{
s[0] = 0;
*length = 0;
}