Cod sursa(job #1354662)

Utilizator info_maniacStefanescu Andrei info_maniac Data 21 februarie 2015 22:35:56
Problema Convertor Scor 100
Compilator c Status done
Runda rosedu_cdl_2015 Marime 3.42 kb
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>


/* usual filesystem block size is 4 KB
 * so a read of 4 KB should minimize the time
 * spent on IO.
 **/
#define BLOCK_SIZE 4096


/* use macros as no function stack operations are nedded
 * better time performance
 * */ 

/* 	reading is done in chuncks
 *	this macro checks if the chunck
 *	is at the end.
 **/
#define check(temp_string, orig, in)	if(*temp_string == '\0') {			   \
											temp_string = orig;				   \
											fgets(temp_string, BLOCK_SIZE, in);\
											if(feof(in)) break;				   \
										}											


/* 	reads through the chunck and
 * 	until it finds the specified char
 **/
#define skip_to_char(str, orig, c, ctrl, fp) do { 							\
												while(*str != c) {			\
													check(str, orig, fp);	\
													if(*str == c) {			\
														break;				\
													}						\
													if(*str == ctrl) {		\
														break;				\
													}						\
													++ str;					\
												}							\
												break;						\
											} while(0)


int main() {

	FILE *in, *out;

	/* assuming files can be opened 
	 * so no checking
 	 **/
	in = fopen("convertor.in", "rt");
	out = fopen("convertor.out", "wt");

	if(in == NULL) {
		/* something wierd with infoarena
 		 * no input file
 		 **/
		return -1;
	}

	if(out == NULL) {
		/* something wierd with infoarena
 		 * no output file can be opened
 		 **/
		fclose(in); /* file was opened */
		return -2;
	}

	/* original chunck */
	char *string = malloc(BLOCK_SIZE * sizeof(char));

	/* used to know when to print a \n*/
	short number_of_keys = 0;

	/* chunck iterator */
	char *temp_string = string;

	fgets(temp_string, BLOCK_SIZE, in);

	/* read labels 
 	 * read the string between ""
 	 * until } is found
 	 **/
	while(1) {
		skip_to_char(temp_string, string, '"', '}', in);
		++ temp_string; /* skip " char */
		check(temp_string, string, in);

		while(*temp_string !=  '"') {
			fprintf(out, "%c", *temp_string);
			++ temp_string;

			check(temp_string, string, in);	
		}

		fprintf(out, ",");
		++ number_of_keys;
		++ temp_string; /* skip the last " */

		/* go to next label */
		skip_to_char(temp_string, string, ',', '}', in);

		/* end of first JSON object */
		if(*temp_string == '}') {
			break;
		}
	}
		
	fprintf(out, "\n");

	/* reset file position */
	fseek(in, 0, SEEK_SET);
	temp_string = string;
	fgets(temp_string, BLOCK_SIZE, in);
	
	/* read values */
	short k = 1;	
	while(!feof(in)) {
		check(temp_string, string, in);	

		skip_to_char(temp_string, string, ':', 0, in);
		if(feof(in)) break;

		++ temp_string;
		check(temp_string, string, in);

		/* 	skip to value 
 		* 	meaning skipping each space,\t,\n etc.
 		* 	until either a " or a digit is found
 		**/
		while(!isdigit(*temp_string) && !(*temp_string == '"')) {
			++ temp_string;
			check(temp_string, string, in);
		}

		if(isdigit(*temp_string)) {
			/* read the integer value */
			while(isdigit(*temp_string)) {
				fprintf(out, "%c", *temp_string);
				++ temp_string;
				check(temp_string, string, in);
			}
		} else {
			++ temp_string; /* skip the " */
			check(temp_string, string, in);	
			
			while(*temp_string != '"') {
				fprintf(out, "%c", *temp_string);
				++ temp_string;
				check(temp_string, string, in);
			}

		}

		if(k == number_of_keys) {
			k = 1;
			fprintf(out, ",\n");
		} else {
			++ k;
			fprintf(out, ",");
		}
	}	

	/* cleanup */
	free(string);
	fclose(in);
	fclose(out);
	

	return 0;
}