home *** CD-ROM | disk | FTP | other *** search
- /*
- * scanfix.c -- scan a fixed-length ASCII string and break
- * out various fields according to the format specifiers
- * supplied.
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <ctype.h>
- #define ANSI
- #ifdef ANSI
- #include <stdarg.h>
- #else
- #include <varargs.h>
- #endif
-
- #define FALSE 0
- #define TRUE !FALSE
-
- #ifdef ANSI
- int scanfix(char *string, char *control, ...)
- #else
- int scanfix(string, control, va_alist)
- char *string, *control;
- va_dcl
- #endif
- {
- char *csPtr; /* control string pointer */
- char *sPtr; /* string pointer */
- char *cPtr; /* ptr for type s and c */
- char *sNextPtr; /* next string pointer */
- char *nonWhite; /* ptr to non-white space */
- char c; /* temporary character */
- char cTemp; /* another temp character */
- char type; /* type of field */
- char longFlag; /* convert to long? */
- char shortFlag; /* convert to short? */
- char skipFlag; /* skip field? */
- char leftJust; /* left justify field? */
- int nFields = 0; /* number of fields */
- int length; /* length of field */
- short *hPtr, shortValue; /* use to convert shorts */
- int *iPtr, intValue; /* use to convert ints */
- long *lPtr, longValue; /* use to convert longs */
- float *fPtr, floatValue; /* use to convert floats */
- double *dPtr, doubleValue; /* use to convert doubles */
- va_list argp; /* argument pointer */
-
- #ifdef ANSI
- va_start(argp, control);
- #else
- va_start(argp); /* init argument pointer */
- #endif
-
- sPtr = string;
- csPtr = control;
-
- /* process format specifiers in the control string */
- while (*csPtr != '\0') {
- /* find next field % identifier */
- if (*(csPtr++) != '%')
- continue;
-
- /* determine if current field is to be skipped */
- skipFlag = FALSE;
- if (*csPtr == '*') {
- skipFlag = TRUE;
- csPtr++;
- }
-
- /* determine if field is to be left-justified */
- leftJust = FALSE;
- if (*csPtr == '-') {
- leftJust = TRUE;
- csPtr++;
- }
-
- /* determine field length */
- length = 0;
- while (isdigit(c = *(csPtr++)))
- length = length * 10 + c - '0';
- if (length == 0)
- break;
-
- /* skip the field if necessary */
- if (skipFlag) {
- sPtr += length;
- continue;
- }
-
- /* determine field type */
- longFlag = FALSE;
- shortFlag = FALSE;
- if (c == 'l') { /* test for long */
- longFlag = TRUE;
- c = *(csPtr++);
- }
- else if (c == 'h') { /* test for short */
- shortFlag = TRUE;
- c = *(csPtr++);
- }
- type = c;
-
- /* check for valid type */
- if (strchr("dscf", type) == NULL)
- break;
-
- /* save first char of next field and */
- /* replace it with \0 */
- sNextPtr = sPtr + length;
- cTemp = *sNextPtr;
- *sNextPtr = '\0';
-
- switch (type) {
- case 'd':
- if (longFlag) {
- lPtr = va_arg(argp, long *);
- longValue = atol(sPtr);
- *lPtr = longValue;
- }
- else if (shortFlag) {
- hPtr = va_arg(argp, short *);
- shortValue = (short) atoi(sPtr);
- *hPtr = shortValue;
- }
- else {
- iPtr = va_arg(argp, int *);
- intValue = atoi(sPtr);
- *iPtr = intValue;
- }
- break;
- case 's':
- case 'c':
- cPtr = va_arg(argp, char *);
- if (leftJust)
- /* skip white space */
- while (isspace(*sPtr) && *sPtr != '\0')
- sPtr++;
- nonWhite = sPtr;
- while(*sPtr != '\0') {
- *cPtr = *(sPtr++);
- if (!isspace(*cPtr))
- nonWhite = cPtr;
- cPtr++;
- } /* while(*sPtr != '\0') */
- if (type == 's') /* null for string */
- *(++nonWhite) = '\0';
- break;
- case 'f':
- if (longFlag) {
- dPtr = va_arg(argp, double *);
- doubleValue = atof(sPtr);
- *dPtr = doubleValue;
- }
- else {
- fPtr = va_arg(argp, float *);
- floatValue = atof(sPtr);
- *fPtr = floatValue;
- }
- break;
- } /* end switch */
- nFields++;
-
- /* restore first character of next field */
- *sNextPtr = cTemp;
- sPtr = sNextPtr;
- } /* end while */
-
- va_end(argp);
-
- if (nFields == 0)
- return(EOF);
- else
- return(nFields);
- }