📄 fiolib.c
字号:
* automatically.* .iP `['* Matches a non-empty sequence of characters from a set of * expected characters (the `scanset'). The corresponding argument* should be a pointer to the initial character of an array large* enough to accept the sequence and a terminating null character,* which is added automatically. The conversion specifier* includes all subsequent character in the format string, up to* and including the matching right bracket (`]'). The characters* between the brackets (the `scanlist') comprise the scanset,* unless the character after the left bracket is a circumflex (`^')* in which case the scanset contains all characters that do not* appear in the scanlist between the circumflex and the right* bracket. If the conversion specifier begins with "[]" or "[^]", the* right bracket character is in the scanlist and the next * right bracket character is the matching right bracket that ends* the specification; otherwise the first right bracket character* is the one that ends the specification.* .iP `c'* Matches a sequence of characters of the number specified by the* field width (1 if no field width is present in the directive).* The corresponding argument should be a pointer to the initial * character of an array large enough to accept the sequence.* No null character is added.* .iP `p'* Matches an implementation-defined set of sequences, which should be* the same as the set of sequences that may be produced by the %p* conversion of the fprintf() function. The corresponding argument* should be a pointer to a pointer to `void'. VxWorks defines its* pointer input field to be consistent with pointers written by the* fprintf() function ("0x" hexadecimal notation). If the input item is* a value converted earlier during the same program execution, the* pointer that results should compare equal to that value; otherwise* the behavior of the %p conversion is undefined.* .iP `n'* No input is consumed. The corresponding argument should be a pointer to* `int' into which the number of characters read from the input stream so* far by this call to sscanf() is written. Execution of a %n directive does* not increment the assignment count returned when sscanf() completes* execution.* .iP `%'* Matches a single `%'; no conversion or assignment occurs. The* complete conversion specification is %%.* .LP** If a conversion specification is invalid, the behavior is undefined.** The conversion specifiers `E', `G', and `X' are also valid and behave the* same as `e', `g', and `x', respectively.** If end-of-file is encountered during input, conversion is terminated. If * end-of-file occurs before any characters matching the current directive* have been read (other than leading white space, where permitted), execution* of the current directive terminates with an input failure; otherwise, unless* execution of the current directive is terminated with a matching failure,* execution of the following directive (if any) is terminated with an input* failure.** If conversion terminates on a conflicting input character, the offending* input character is left unread in the input stream. Trailing white space* (including new-line characters) is left unread unless matched by a* directive. The success of literal matches and suppressed assignments is* not directly determinable other than via the %n directive.** INCLUDE FILES: fioLib.h ** RETURNS:* The number of input items assigned, which can be fewer than provided for,* or even zero, in the event of an early matching failure; or EOF if an* input failure occurs before any conversion.** SEE ALSO: fscanf(), scanf(),* .I "American National Standard for Information Systems -"* .I "Programming Language - C, ANSI X3.159-1989: Input/Output (stdio.h)"** VARARGS2*/int sscanf ( const char * str, /* string to scan */ const char * fmt, /* format string */ ... /* optional arguments to format string */ ) { int nArgs; int unget; va_list vaList; /* vararg list */ va_start (vaList, fmt); nArgs = fioScanV (fmt, getbuf, (int) &str, &unget, vaList); va_end (vaList); return (nArgs); }/********************************************************************************* getbuf - sscanf() support routine: get next character in string** RETURNS: Next character or EOF if empty.*/LOCAL int getbuf ( char **str ) { int c = (int)(**str); if (c == EOS) return (EOF); ++*str; return (c); }/******************************************************************************** fioScanV - scan processor** NOMANUAL*/int fioScanV ( const char *fmt, /* the format string */ FUNCPTR getRtn, /* routine to get next character */ int getArg, /* argument to be passed to get */ int * pUnget, /* where to return unget char (-1 = no unget) */ va_list vaList /* vararg list */ ) { BOOL suppress; /* assignment was suppressed */ void * pArg; int ch; BOOL countArg; /* FALSE for %n, not counted */ BOOL quit = FALSE; int argsAssigned = 0; int nchars = 0; pArg = va_arg (vaList, void *); /* get first pointer arg */ ch = (* getRtn) (getArg); /* get first char */ while (!quit && (*fmt != EOS)) { countArg = TRUE; /* default = count arg assignment */ switch (*fmt) { case ' ': case '\n': case '\t': /* skip white space in string */ ++fmt; while (isspace (ch)) GET_CHAR (ch, nchars); break; case '%': /* conversion specification */ ++fmt; /* NOTE: if next char is '%' (i.e. "%%") then a normal match * of '%' is required: FALL THROUGH to default case */ if (*fmt != '%') { /* Skip white space except for 'c', 'n', '[' specifiers. * Suppress including %n fields in returned count. */ switch (*fmt) { case 'c': case '[': break; case '*': /* ignore the '*' for purposes of white * space removal */ switch(*(fmt+1)) { case 'c': case '[': break; default: while (isspace (ch)) GET_CHAR (ch, nchars); } break; case 'n': countArg = FALSE; /* we don't count %n */ break; case 'h': /* %hn, %ln, %Ln */ case 'l': case 'L': if (*(fmt + 1) == 'n') { countArg = FALSE; break; } default: while (isspace (ch)) GET_CHAR (ch, nchars); } /* Quit if at end of input string, unless spec is %[hl]n */ if (ch == EOF) /* if at end of input */ { switch (*fmt) { case 'n': break; /* %n is still valid */ case 'h': /* also %hn, %ln, %Ln */ case 'l': case 'L': { if (*(fmt + 1) == 'n') break; /* keep going */ } /* FALL THROUGH */ default: quit = TRUE; break; } } /* Scan field in input string */ if (scanField (&fmt, pArg, getRtn, getArg, &suppress, &ch, &nchars)) { /* successful scan */ if (!suppress) { if (countArg) /* unless arg was %n */ ++argsAssigned; /* increment count */ pArg = va_arg (vaList, void *); /* next arg */ } } else quit = TRUE; /* unsuccessful */ break; } /* NOTE: else of above if FALLS THROUGH to default below! */ default: /* character to match */ if (ch == *fmt) { GET_CHAR (ch, nchars); /* advance past matched char */ ++fmt; /* advance past matched char */ } else quit = TRUE; /* match failed */ break; } } *pUnget = ch; if ((argsAssigned == 0) && (ch == EOF)) return (EOF); return (argsAssigned); }/********************************************************************************* scanField - assign value to argument according to format** RETURNS:* TRUE if conversion successful, otherwise FALSE;* <pSuppress> is set TRUE if assignment was suppressed.** NOMANUAL*/ /*LOCAL*/ BOOL scanField ( const char **ppFmt, /* conversion specification string */ FAST void * pReturn, /* where to set result */ FUNCPTR getRtn, int getArg, BOOL * pSuppress, /* set to TRUE if argptr was not assigned */ int * pCh, int * pNchars ) { FAST int fieldwidth = 0; /* maximum number of chars to convert. * default 0 implies no limit */ int returnSpec = 0; /* 0, 'h', 'l', L' */ FAST const char *pFmt = *ppFmt; /* ptr to current char in fmt string */ FAST int base; /* check for assignment suppression */ if (*pSuppress = (*pFmt == '*')) { ++pFmt; pReturn = NULL; } /* check for specification of maximum fieldwidth */ while (isdigit (*pFmt)) fieldwidth = 10 * fieldwidth + (*pFmt++ - '0'); /* check for specification of size of returned value */ switch (*pFmt) { case 'h': case 'l': case 'L': returnSpec = *pFmt++; break; } /* set default fieldwidth if not specified */ if (fieldwidth == 0) fieldwidth = (*pFmt == 'c') ? 1 : INT_MAX; switch (*pFmt) { case 'c': /* character, or character array */ if (!scanChar ((char *) pReturn, fieldwidth, getRtn, getArg, pCh, pNchars)) return (FALSE); /* unsuccessful conversion */ break; case 'i': /* integer */ case 'o': /* octal integer */ case 'd': /* decimal integer */ case 'u': /* unsigned decimal integer */ case 'x': /* hex integer */ case 'X': /* hex integer */ case 'p': /* pointer */ switch (*pFmt) { case 'i': base = 0; break; case 'o': base = 8; break; case 'd': base = 10; break; case 'u': base = 10; break; case 'x': base = 16; break; case 'X': base = 16; break; case 'p': base = 16; break; default : base = 0; break; } if (!scanNum (base, pReturn, returnSpec, fieldwidth, getRtn, getArg, pCh, pNchars)) return (FALSE); /* unsuccessful conversion */ break; case 'e': /* exponential float */ case 'f': /* float */ case 'g': /* float */ case 'E': /* exponential double */ case 'F': /* double */ case 'G': /* double */ if ((fioFltScanRtn == NULL) || (!(* fioFltScanRtn) (pReturn, returnSpec, fieldwidth, getRtn, getArg, pCh, pNchars))) return (FALSE); /* unsuccessful conversion */ break; case 's': /* string */ if (!scanString ((char *) pReturn, f
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -