lolamontes69

K+R Exercise7_3

Sep 25th, 2014
144
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.90 KB | None | 0 0
  1. /* Revise minprintf() to handle more of the other facilities of printf()
  2.    implemented ( %d  %5d  %-5d  %.2f  %1.2g  %-3.4s )
  3.  
  4. %*d %.*d etc unimplemented.
  5.  
  6.    too many args causes a segmentation error instead of an error message.
  7.    try-except not implemented
  8.  
  9.      just ignores rogue %'s if included  "frog % lemo"
  10. -2233 % -2233-
  11. -2233  -2233-
  12.     this normally produces an exception
  13.  
  14. -2233 %roggy-stuff -2233-
  15. -2233 roggy-stuff -2233-
  16.  
  17.  
  18. # in Python it skips blanks and formats with the first letter found
  19.  
  20. print "froggy % stuff %d" % ("tree",3)
  21. froggy treetuff 3
  22.  
  23. >>> print "froggy % muff %d" % ("tree",3)
  24. Traceback (most recent call last):
  25.   File "<stdin>", line 1, in <module>
  26. ValueError: unsupported format character 'm' (0x6d) at index 9
  27.  
  28.  
  29. */
  30.  
  31. #include <stdio.h>
  32. #include <stdlib.h>
  33. #include <stdarg.h>  /* va_list and args */
  34.  
  35. #define MAXTOKEN 1000
  36.  
  37. int minprintf(char *fmt, ...);  /* '...' - accept all the args after fmt */
  38. char * makeStr(char *m, char c, int ia1, int dpoi, int dpoi2, int iarg, int jarg);
  39.  
  40. #define maketh makeStr(mstr, type, ia1, dpoi, dpoi2, iarg, jarg) /* macro */
  41.  
  42. main()
  43. {
  44.     int i = 69;
  45.     float j = 0.000232;
  46.     char k[]="frog";
  47.     char *m = &k[0];
  48.    
  49.     minprintf("There %   -2.1c %% %12.4f -2233 -2233- .. *** was %-10.2s at %12p\n",i,j,k,m);
  50.  
  51.     return 0;
  52. }
  53.  
  54. /* minprintf: minimal printf with variable arguement list */
  55. int minprintf(char *fmt, ...)
  56. {
  57.     va_list ap;          /* points to each unnamed arg in turn  */
  58.     char mstr[MAXTOKEN]; /* make string in outside function     */
  59.     char *p, *sval, *temp1;
  60.     int ival, type, iarg=0, ia1=0, jarg=0, dpoi=0, dpoi2=0, ineg;
  61.     double dval;
  62.     void *pval;
  63.  
  64.     va_start(ap, fmt);   /* make ap point to the 1st unnamed arg */
  65.     for(p=fmt; *p; p++) {
  66.         if(*p != '%') {
  67.             putchar(*p);
  68.             continue;
  69.         }
  70.         type = *++p;
  71.         while(type==' ')  /* Default behaviour seems to be to skip spaces */
  72.             type = *++p;  /* and match with the first chars found after   */
  73.         if(type=='-') {
  74.             ineg=1;
  75.             type = *++p;
  76.         } if(type=='-') {
  77.             puts("\nerror: invalid formatting '%--'");
  78.             return -1;
  79.         } if(type=='.') {
  80.             if(ineg) {
  81.                 puts("\nerror: invalid formatting '-.'");
  82.                 return -1;
  83.             }
  84.             dpoi = 1;
  85.             type = *++p;
  86.         } if(isdigit(type)) {
  87.             iarg = atoi(p);
  88.             ia1 = 1;
  89.             while(isdigit(*++p))
  90.                 ;
  91.             if(ineg) {
  92.                iarg-=(iarg*2);
  93.                ineg = 0;
  94.             } type = *p;
  95.         } if(type=='.') {
  96.             if(dpoi) {
  97.                 puts("\nerror: invalid formatting '.XX.'");
  98.                 return -1;
  99.             }
  100.             dpoi2 = 1;
  101.             type = *++p;
  102.         } if(isdigit(type)) {
  103.             jarg = atoi(p);
  104.             ia1 = 1;
  105.             while(isdigit(*++p))
  106.                 ;
  107.             type = *p;
  108.         } if(type=='.') {
  109.                 puts("\nerror: invalid formatting '.X.X.'");
  110.                 return -1;
  111.         }
  112.         switch(type) {
  113.             case '%':
  114.                 printf("%%");
  115.                 break;
  116.             case 'd':
  117.                 ival = va_arg(ap, int);
  118.                 temp1 = maketh;
  119.                 printf(temp1,ival);
  120.                 break;
  121.             case 'i':
  122.                 ival = va_arg(ap, int);
  123.                 temp1 = maketh;
  124.                 printf(temp1,ival);
  125.                 break;
  126.             case 'o':
  127.                 ival = va_arg(ap, int);
  128.                 temp1 = maketh;
  129.                 printf(temp1,ival);
  130.                 break;
  131.             case 'x':
  132.                 ival = va_arg(ap, int);
  133.                 temp1 = maketh;
  134.                 printf(temp1,ival);
  135.                 break;
  136.             case 'X':
  137.                 ival = va_arg(ap, int);
  138.                 temp1 = maketh;
  139.                 printf(temp1,ival);
  140.                 break;
  141.             case 'u':
  142.                 ival = va_arg(ap, int);
  143.                 temp1 = maketh;
  144.                 printf(temp1,ival);
  145.                 break;
  146.             case 'c':
  147.                 ival = va_arg(ap, int);
  148.                 temp1 = maketh;
  149.                 printf(temp1,ival);
  150.                 break;
  151.             case 'f':
  152.                 dval = va_arg(ap, double);
  153.                 temp1 = maketh;
  154.                 printf(temp1,dval);
  155.                 break;
  156.             case 'e':
  157.                 dval = va_arg(ap, double);
  158.                 temp1 = maketh;
  159.                 printf(temp1,dval);
  160.                 break;
  161.             case 'E':
  162.                 dval = va_arg(ap, double);
  163.                 temp1 = maketh;
  164.                 printf(temp1,dval);
  165.                 break;
  166.             case 'g':
  167.                 dval = va_arg(ap, double);
  168.                 temp1 = maketh;
  169.                 printf(temp1,dval);
  170.                 break;
  171.             case 'G':
  172.                 dval = va_arg(ap, double);
  173.                 temp1 = maketh;
  174.                 printf(temp1,dval);
  175.                 break;
  176.             case 's':
  177.                 if(!ia1) {
  178.                     for(sval = va_arg(ap, char *); *sval; sval++)
  179.                         putchar(*sval);
  180.                     break;
  181.                 }
  182.                 else {
  183.                     sval = va_arg(ap, char *);
  184.                     temp1 = maketh;
  185.                     printf(temp1,sval);
  186.                     for( ; *sval; sval++) /* pass the rest of the string away */
  187.                         ;
  188.                     break;
  189.                 }
  190.             case 'p':
  191.                 pval = va_arg(ap, void *);
  192.                 temp1 = maketh;
  193.                 printf(temp1,pval);
  194.                 break;
  195.             default:
  196.                 putchar(*p);
  197.                 break;
  198.             }
  199.             ia1   = 0;  /* flag that num args are being used    */
  200.             iarg  = 0;
  201.             jarg  = 0;
  202.             dpoi  = 0;  /* flags that decimal point is included */
  203.             dpoi2 = 0;  /*   "    "     "       "    "    "     */
  204.         }
  205.         va_end(ap);     /* clean up when done                   */
  206. }
  207.  
  208. /* makeStr: create and return the formatting string */
  209. char * makeStr(char *m, char c, int ia1, int dpoi, int dpoi2, int iarg, int jarg)
  210. {
  211.     int i=0;
  212.     char res[MAXTOKEN];
  213.  
  214.     if(!ia1) {
  215.         char f[] = "%%c", c;            /* e.g., %f     */
  216.         sprintf(m,f,c);
  217.     } else {
  218.         if(!dpoi && !dpoi2) {           /* e.g., %3f    */
  219.             char f[] = "%%%c";
  220.             sprintf(m,f,c);
  221.         } else if(dpoi){
  222.             char f[] = "%%%%.%%d%c";    /* e.g., %.3f   */
  223.             sprintf(res,f,c);
  224.             sprintf(m,res,iarg);
  225.         } else {
  226.             char f[] = "%%%%%%d.%%d%c"; /* e.g., %62.3f */
  227.             sprintf(res,f,c);
  228.             sprintf(m,res,iarg,jarg);
  229.         }
  230.     }
  231.     return m;
  232. }
Advertisement
Add Comment
Please, Sign In to add comment