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