home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / pctchnqs / 1991 / number4 / scanfix.c < prev    next >
Text File  |  1991-08-01  |  4KB  |  175 lines

  1. /*
  2.  *  scanfix.c -- scan a fixed-length ASCII string and break
  3.  *  out various fields according to the format specifiers
  4.  *  supplied.
  5.  */
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <ctype.h>
  9. #define ANSI
  10. #ifdef ANSI
  11. #include <stdarg.h>
  12. #else
  13. #include <varargs.h>
  14. #endif
  15.  
  16. #define FALSE 0
  17. #define TRUE !FALSE
  18.  
  19. #ifdef ANSI
  20. int scanfix(char *string, char *control, ...)
  21. #else
  22. int scanfix(string, control, va_alist)
  23. char *string, *control;
  24. va_dcl
  25. #endif
  26. {
  27.     char    *csPtr;             /* control string pointer */
  28.     char    *sPtr;              /* string pointer */
  29.     char    *cPtr;              /* ptr for type s and c */
  30.     char    *sNextPtr;          /* next string pointer */
  31.     char    *nonWhite;          /* ptr to non-white space */
  32.     char    c;                  /* temporary character */
  33.     char    cTemp;              /* another temp character */
  34.     char    type;               /* type of field */
  35.     char    longFlag;           /* convert to long? */
  36.     char    shortFlag;          /* convert to short? */
  37.     char    skipFlag;           /* skip field? */
  38.     char    leftJust;           /* left justify field? */
  39.     int     nFields = 0;        /* number of fields */
  40.     int     length;             /* length of field */
  41.     short   *hPtr, shortValue;  /* use to convert shorts */
  42.     int     *iPtr, intValue;    /* use to convert ints */
  43.     long    *lPtr, longValue;   /* use to convert longs */
  44.     float   *fPtr, floatValue;  /* use to convert floats */
  45.     double  *dPtr, doubleValue; /* use to convert doubles */
  46.     va_list argp;               /* argument pointer */
  47.  
  48. #ifdef ANSI
  49.     va_start(argp, control);
  50. #else
  51.     va_start(argp);             /* init argument pointer */
  52. #endif
  53.  
  54.     sPtr = string;
  55.     csPtr = control;
  56.  
  57.     /* process format specifiers in the control string */
  58.     while (*csPtr != '\0') {
  59.         /* find next field % identifier */
  60.         if (*(csPtr++) != '%')
  61.             continue;
  62.  
  63.         /* determine if current field is to be skipped */
  64.         skipFlag = FALSE;
  65.         if (*csPtr == '*') {
  66.             skipFlag = TRUE;
  67.             csPtr++;
  68.         }
  69.  
  70.         /* determine if field is to be left-justified */
  71.         leftJust = FALSE;
  72.         if (*csPtr == '-') {
  73.             leftJust = TRUE;
  74.             csPtr++;
  75.         }
  76.  
  77.         /* determine field length */
  78.         length = 0;
  79.         while (isdigit(c = *(csPtr++)))
  80.             length = length * 10 + c - '0';
  81.         if (length == 0)
  82.             break;
  83.  
  84.         /* skip the field if necessary */
  85.         if (skipFlag) {
  86.             sPtr += length;
  87.             continue;
  88.         }
  89.  
  90.         /* determine field type */
  91.         longFlag = FALSE;
  92.         shortFlag = FALSE;
  93.         if (c == 'l') {                 /* test for long */
  94.             longFlag = TRUE;
  95.             c = *(csPtr++);
  96.         }
  97.         else if (c == 'h') {            /* test for short */
  98.             shortFlag = TRUE;
  99.             c = *(csPtr++);
  100.         }
  101.         type = c;
  102.  
  103.         /* check for valid type */
  104.         if (strchr("dscf", type) == NULL)
  105.             break;
  106.  
  107.         /* save first char of next field and */
  108.         /* replace it with \0                */
  109.         sNextPtr = sPtr + length;
  110.         cTemp = *sNextPtr;
  111.         *sNextPtr = '\0';
  112.  
  113.         switch (type) {
  114.             case 'd':
  115.                if (longFlag) {
  116.                 lPtr = va_arg(argp, long *);
  117.                 longValue = atol(sPtr);
  118.                 *lPtr = longValue;
  119.                 }
  120.                else if (shortFlag) {
  121.                 hPtr = va_arg(argp, short *);
  122.                 shortValue = (short) atoi(sPtr);
  123.                 *hPtr = shortValue;
  124.                 }
  125.                else {
  126.                 iPtr = va_arg(argp, int *);
  127.                 intValue = atoi(sPtr);
  128.                 *iPtr = intValue;
  129.                 }
  130.                break;
  131.             case 's':
  132.             case 'c':
  133.                cPtr = va_arg(argp, char *);
  134.                if (leftJust)
  135.                /* skip white space */
  136.                  while (isspace(*sPtr) && *sPtr != '\0')
  137.                  sPtr++;
  138.                nonWhite = sPtr;
  139.                while(*sPtr != '\0') {
  140.                 *cPtr = *(sPtr++);
  141.                 if (!isspace(*cPtr))
  142.                     nonWhite = cPtr;
  143.                 cPtr++;
  144.                 } /* while(*sPtr != '\0') */
  145.                if (type == 's')    /* null for string */
  146.                 *(++nonWhite) = '\0';
  147.                break;
  148.             case 'f':
  149.                if (longFlag) {
  150.                 dPtr = va_arg(argp, double *);
  151.                 doubleValue = atof(sPtr);
  152.                 *dPtr = doubleValue;
  153.                 }
  154.                else {
  155.                 fPtr = va_arg(argp, float *);
  156.                 floatValue = atof(sPtr);
  157.                 *fPtr = floatValue;
  158.                 }
  159.                break;
  160.         } /* end switch */
  161.         nFields++;
  162.  
  163.         /* restore first character of next field */
  164.         *sNextPtr = cTemp;
  165.         sPtr = sNextPtr;
  166.     } /* end while */
  167.  
  168.     va_end(argp);
  169.  
  170.     if (nFields == 0)
  171.         return(EOF);
  172.     else
  173.         return(nFields);
  174. }
  175.