lolamontes69

K+R Exercise7_4

Sep 25th, 2014
210
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.97 KB | None | 0 0
  1. /* Write a private version of scanf analogous to minprintf() from the previous section
  2.  * For comments versions see previous versions
  3. --------------------------------
  4. sh-4.1# ./exercise7_4                  
  5. formatting string =  %4[0-9]%f%s
  6. 1212 2.121 FROGGY
  7. k  = 1212
  8. j  = 2.121000
  9. k1 = FROGGY
  10. --------------------------------
  11.  
  12.    because we are making the calls to scanf() the same behaviours that scanf()
  13.    exhibits occur with minscanf().
  14.  
  15. */
  16.  
  17. #include <stdio.h>
  18. #include <stdarg.h>  /* va_list and args */
  19.  
  20. #define MAXCHAR 100    /* maximum number of chars in char foobar[] */
  21. #define NUMBER 0
  22.  
  23. int minscanf(char *fmt, ...);
  24.  
  25. main()
  26. {
  27.     int i, res;
  28.     float j;
  29.     char k[MAXCHAR];
  30.     char k1[MAXCHAR];
  31.     int m;
  32.  
  33.     res = minscanf("%4[0-9]%f%s", k, &j, k1); /* going over string width returns error
  34.                                                   or overflows into the next formatting */
  35.     if(res!=0) {
  36.         printf("k  = %s\n",k);
  37.         printf("j  = %f\n",j);
  38.         printf("k1 = %s\n",k1);    
  39.     } else puts("Error received from minscanf()");
  40.     return 0;
  41. }
  42.  
  43.  
  44. int minscanf(char *fmt, ...)
  45. {
  46.     int i, res, type, wasnum=0, numarg=0, mrclean=0;
  47.     char *p;
  48.     char *temp;
  49.     char temp1[MAXCHAR];
  50.     char formstr[MAXCHAR];
  51.     int *ival;
  52.     float *dval;
  53.     char *sval;
  54.  
  55.     /* i is an iterator
  56.      * res is the return value from scanf()
  57.      * type is the current char in *p
  58.      * wasnum is a flag for if a NUMBER has just been parsed
  59.      * numarg is a store for the lhs of the decimal point in the formatting string
  60.      * mrclean is a flag for resetting the variables instead of after each case
  61.      * *p is the pointer to fmt
  62.      * temp is for the formatting string
  63.      * temp1 is for the %[XXX] formatting strings contents
  64.      * ival, dval, sval are pointers to the ... args
  65.      * fmt is the formatting string sent from main()                                 */
  66.  
  67.  
  68.     va_list ap;                 /* initialize */
  69.     va_start(ap, fmt);          /* pass the variables after char *j */
  70.  
  71.     printf("formatting string =  %s\n",fmt);
  72.     for(p = fmt; *p; *p++) {
  73.         if(*p != '%' && !wasnum) return 0;
  74.             /* '*p' because we are dereferencing 'p' for its contents
  75.              * No errors if string being parsed properly
  76.              * the outer for loop increments after the switch loop finishes   */
  77.         type = *++p; /* Increment to the next item from the formatting string */
  78.         if(type>='0' && type<='9')
  79.             type=NUMBER;
  80.         switch(type) {
  81.             case NUMBER:/* parses one number at a time */
  82.                 numarg = (numarg * 10) + ((*p)-'0');
  83.                 wasnum = 1;
  84.                 *--p;  /* This is to balance the 'type = *++p;' after the forloops '*p++' */
  85.                 break;
  86.             case 'd':  
  87.                 ival = va_arg(ap, int *); /* ival now points to ap */
  88.                                           /* forgetting anything it used to point to */
  89.                 if(wasnum) {
  90.                     char *temp = formstr;
  91.                     sprintf(temp,"%%%d%c",numarg,type);
  92.                     res = scanf(temp,ival);
  93.                 } else res = scanf("%d", ival);
  94.                 if(res==0)  return 0;
  95.                 mrclean = 1;
  96.                 break;
  97.             case 'f':
  98.                 dval = va_arg(ap, float *);
  99.                 if(wasnum) {
  100.                     char *temp = formstr;
  101.                     sprintf(temp,"%%%d%c",numarg,type);
  102.                     res = scanf(temp,dval);
  103.                 } else res = scanf("%f", dval);
  104.                 if(res==0) return 0;
  105.                 mrclean = 1;
  106.                 break;
  107.             case 's':
  108.                 sval = va_arg(ap, char *);
  109.                 if(wasnum) {
  110.                     char *temp = formstr;
  111.                     sprintf(temp,"%%%d%c",numarg,type);
  112.                     res = scanf(temp, sval);
  113.                 } else res = scanf("%s", sval);
  114.                 if(res==0)  return 0;
  115.                 mrclean = 1;
  116.                 break;
  117.             case '[':
  118.                 sval = va_arg(ap, char *);
  119.                 char *temp = formstr;
  120.                 for(i=0; *p!=']'; *++p, i++)
  121.                     temp1[i] = *p;
  122.                 temp1[i] = *p;
  123.                 temp1[i+1] = '\0';
  124.                 if(wasnum) {
  125.                     sprintf(temp,"%%%d%s%c",numarg,temp1,type);
  126.                     res = scanf(temp, sval);
  127.                 } else {
  128.                     sprintf(temp,"%%%s%c",temp1,type);
  129.                     res = scanf(temp, sval);
  130.                 }
  131.                 mrclean = 1;
  132.                 break;
  133.             default:
  134.                 puts("was none of the above");
  135.                 return 0;
  136.         }
  137.         if(mrclean) {
  138.             wasnum = 0;     /* reset number flag */
  139.             numarg = 0;     /* and number stores */
  140.             mrclean = 0;
  141.         }
  142.     }
  143.     va_end(ap);             /* end the va_list routine */
  144.     return res;
  145. }
Advertisement
Add Comment
Please, Sign In to add comment