|
Programiranje Programski jezici, tehnike, alatke... |
|
Alatke vezane za temu | Vrste prikaza |
20.11.2013, 23:46 | #1 |
Član
Član od: 14.4.2010.
Lokacija: Podgorica
Poruke: 332
Zahvalnice: 61
Zahvaljeno 11 puta na 11 poruka
|
C, moj printf
Profesor je zadao zadatak za vecu ocjenu/dodatne bodove da sami ispisemo printf funkciju koristeci sistemske pozive u linux sistemu (prvenstveno read i write).
Do sada sto sam ispisao: Kod:
#include <stdio.h> #include <stdlib.h> #include <stdarg.h> #include <string.h> /* flegovi */ #define NO_FLAG 0 #define MINUS_FLAG 1 #define PLUS_FLAG 2 #define SPACE_FLAG 3 #define HASH_FLAG 4 #define ZERO_FLAG 5 /* tipovi */ #define __hh 8 #define __h 16 #define __l 24 #define __ll 32 #define __L 40 #define __d 0 #define __i 1 #define __u 2 #define __o 3 #define __x 4 #define __f 5 #define __c 6 #define __s 7 void mprintf(const char*, ...); int is_digit(char); int is_flag(char); int get_flag_spec(char); int digit(char); int is_valid_spec(char); int main() { int x = 30; mprintf("x=%-5.4hhd %lf lazar", x); //printf("%d", 16); return 0; } void mprintf(const char* format, ...) { va_list arguments; int flen = strlen(format); int poz = 0; va_start(arguments, format); while(poz < flen) { if( format[poz] == '%') { poz++; int flag=0, sirina=0, preciznost=0; char specbuffer[3] = {'\0'}; if(is_flag(format[poz])) { flag = get_flag_spec(format[poz]); poz++; } while(is_digit(format[poz])){sirina=sirina*10+digit(format[poz]);poz++;} /*Uzima sirinu polja*/ if(format[poz]=='.'){poz++;while(is_digit(format[poz])){preciznost=preciznost*10+digit(format[poz]);poz++;}} /*Uzima preciznost*/ int i=0; while(is_valid_spec(format[poz])) { specbuffer[i]=format[poz]; i++; poz++; if(i > 3 || poz > flen) { /* obradi gresku */ } } int specflag = 0; /* integers */ if(strcmp(specbuffer, "hhd")) specflag = __hh | __d; /*signed char*/ else if(strcmp(specbuffer, "hd")) specflag = __h | __d; /*short int*/ else if(strcmp(specbuffer, "ld")) specflag = __l | __d; /*long int*/ else if(strcmp(specbuffer, "lld")) specflag = __ll | __d; /*long long int*/ else if(strcmp(specbuffer, "hhi")) specflag = __hh | __i; else if(strcmp(specbuffer, "hi")) specflag = __h | __i; else if(strcmp(specbuffer, "li")) specflag = __l | __i; else if(strcmp(specbuffer, "lli")) specflag = __ll | __i; else if(strcmp(specbuffer, "d")) specflag = __d; /*int*/ else if(strcmp(specbuffer, "i")) specflag = __i; /*int*/ /*unsigned*/ else if(strcmp(specbuffer, "hhu")) specflag = __hh | __u; // unsigned char else if(strcmp(specbuffer, "hu")) specflag = __h | __u; // unsigned short int else if(strcmp(specbuffer, "lu")) specflag = __l | __u; // unsigned long int else if(strcmp(specbuffer, "llu")) specflag = __ll | __u; // unsigned long long int else if(strcmp(specbuffer, "u")) specflag = __u; // unsigned int /*octal*/ else if(strcmp(specbuffer, "hho")) specflag = __hh | __o; else if(strcmp(specbuffer, "ho")) specflag = __h | __o; else if(strcmp(specbuffer, "lo")) specflag = __l | __o; else if(strcmp(specbuffer, "llo")) specflag = __ll | __o; else if(strcmp(specbuffer, "o")) specflag = __o; /*hexa*/ else if(strcmp(specbuffer, "hhx")) specflag = __hh | __x; else if(strcmp(specbuffer, "hx")) specflag = __h | __x; else if(strcmp(specbuffer, "lx")) specflag = __l | __x; else if(strcmp(specbuffer, "llx")) specflag = __ll | __x; else if(strcmp(specbuffer, "x")) specflag = __x; /*float, double*/ else if(strcmp(specbuffer, "Lf")) specflag = __L | __f; // long double else if(strcmp(specbuffer, "f")) specflag = __f; //double /*char*/ else if(strcmp(specbuffer, "c")) specflag = __c; // char /*string*/ else if(strcmp(specbuffer, "s")) specflag = __s; //char* // Odstampati na osnovu datih parametara } else write(1, &format[poz], sizeof(char)); poz++; } va_end(arguments); } int is_digit(char c) { if( c >= '0' && c <= '9' ) return 1; return 0; } int is_flag(char c) { if( c == '-' || c == '+' || c == '#' || c == ' ' || c == '0' ) return 1; return 0; } int get_flag_spec(char c) { if( c == '-' ) return MINUS_FLAG; else if( c == '+' ) return PLUS_FLAG; else if( c == '#' ) return HASH_FLAG; else if( c == ' ' ) return SPACE_FLAG; else if( c == '0' ) return ZERO_FLAG; else return NO_FLAG; } int digit(char c) { return c - '0'; } int is_valid_spec(char c) { switch(c) { case 'd': case 'i': case 'o': case 'u': case 'x': case 'f': case 'c': case 's': return 1; case 'h': case 'l': case 'L': return 1; default: return 0; } } Naravno nisam uzeo sve moguce specifikator vec one najosnovnije. Najveci mi je problem izvlacenje ovih specifikatora - oni su oblika %flag|width.precision|type, type mislim na lld, d, f |
21.11.2013, 20:24 | #3 |
Veteran
|
Re: C, moj printf
Napravio si veliku papazjaniju sa tim specbufferom koliko vidim... Po meni bi najlepse resenje bilo da izmodeliras konacni deterministicki automat. Nacrtaj ga na papiru, malo apstrakcije nikad nije na odmet Posle ce programiranje ici manje vise samo od sebe
|
Sledeći korisnik se zahvaljuje korisniku Stevvan na korisnoj poruci: | ||
clzola (22.11.2013) |
Bookmarks sajtovi |
Alatke vezane za temu | |
Vrste prikaza | |
|
|
Slične teme | ||||
tema | temu započeo | forum | Odgovora | Poslednja poruka |
Seminarski iz C-a | Twisterzemun | Programiranje | 9 | 11.12.2012 23:27 |
Meni u Turbo C-u...HITNO | duschan | Programiranje | 8 | 17.2.2008 12:42 |
Printf i Scanf u jeziku C | Loole | Programiranje | 5 | 15.12.2006 14:44 |