📄 _scanfi.c
字号:
/* following conditions: */
/* */
/* '.' : a '.', an 'e', or an 'E' has not yet been encountered */
/* 'e' or 'E' : neither of these characters have been encounterd yet */
/* '+' or '-' : If the last character read was an 'E' or an 'e' */
/*------------------------------------------------------------------------*/
while((inchar >= '0' && inchar <= '9') || inchar == '.' || inchar == 'e'
|| inchar == 'E' || inchar == '+' || inchar == '-')
{
switch(inchar)
{
case '.' : if (dec_flag || e_flag) { invalid = 1; break; }
else dec_flag = 1;
break;
case 'e' :
case 'E' : if (e_flag) { invalid = 1; break; }
else e_flag = 1;
break;
case '+' :
case '-' : if (*(tmpptr-1) != 'E' && *(tmpptr-1) != 'e')
{ invalid = 1; break; }
}
if (invalid) break;
*(tmpptr++) = inchar;
inchar = _inpchar(inp);
if (inchar != EOF) (*num_read)++;
w_counter--;
}
_uninpchar(inp, inchar);
(*num_read)--;
*tmpptr = '\0';
if (bnum_read == *num_read) return(EOF);
return(1);
}
/*****************************************************************************/
/* _SPROC_STR - Copy a string from the input source to a temporary string */
/* */
/* This function takes a string from the input source, and copies it */
/* into a temporary string, to be later assigned to a scanf argument. */
/* */
/*****************************************************************************/
static int _sproc_str(int w_counter, int (*_inpchar)(void **inp),
void (*_uninpchar)(void **inp, char outchar),
char *tmpptr, char conv, void **inp, int *num_read)
{
/*------------------------------------------------------------------------*/
/* Local variables */
/*------------------------------------------------------------------------*/
signed char inchar;
int bnum_read = *num_read;
/*------------------------------------------------------------------------*/
/* If no precision was given for the %c conversion, set it to one. */
/*------------------------------------------------------------------------*/
if ((conv == 'c') && (w_counter < 0)) w_counter = 1;
/*------------------------------------------------------------------------*/
/* Read in the next character, then while that character is not a white */
/* space character, a null terminator, an EOF character, and the field */
/* width has not been exceeded, copy it to the temporary string, and */
/* get another character. */
/*------------------------------------------------------------------------*/
inchar = _inpchar(inp);
(*num_read)++;
while((conv == 'c' || !isspace(inchar)) && inchar != '\0' &&
inchar != EOF && w_counter--)
{
if (tmpptr) *(tmpptr++) = inchar;
inchar = _inpchar(inp);
(*num_read)++;
}
/*------------------------------------------------------------------------*/
/* The %s conversion specifies that a null terminator be placed at the */
/* end of the conversion. */
/*------------------------------------------------------------------------*/
if (conv == 's' && tmpptr) *tmpptr = '\0';
_uninpchar(inp, inchar);
(*num_read)--;
if (bnum_read == *num_read) return(EOF);
return(1);
}
/*****************************************************************************/
/* _SPROC_LB - Process the %[ conversion */
/* */
/* This function copies characters from the input stream into a */
/* temporary string until it satisfies the field width, or encounters a */
/* character that is not in the scanset. The scanset is defined as the */
/* characters passed between the left and right brackets. If a '^' is */
/* first character after the left bracket, then the scanset is every */
/* character that is not listed between the two brackets. */
/* */
/*****************************************************************************/
static int _sproc_lb(int (*_inpchar)(void **inp),
void (*_uninpchar)(void **inp, char outchar),
char *tmpptr, _SFIELD *sfield, void **inp, int *num_read)
{
/*------------------------------------------------------------------------*/
/* Local variables */
/*------------------------------------------------------------------------*/
signed char inchar;
int bnum_read = *num_read;
int w_counter = sfield->fwidth;
int test;
inchar = _inpchar(inp);
(*num_read)++;
for (; w_counter != 0 && inchar != EOF; w_counter--)
{
test = (strrchr(sfield->scanset, inchar) != NULL);
if (_STCHK(sfield, _SFCIRC)) test = !test;
if (test)
{
*(tmpptr++) = inchar;
inchar = _inpchar(inp);
(*num_read)++;
}
else
{
_uninpchar(inp, inchar);
(*num_read)--;
break;
}
}
*tmpptr = '\0';
if (bnum_read == *num_read) return(EOF);
return(1);
}
/*****************************************************************************/
/* _SSET_ARG - Assign the converted value to the next argument */
/* */
/* This function takes a pointer to the result conversion string, and */
/* assigns it to the next argument. The type of argument to be assigned */
/* is determined by the conversion specifier, and the h, l, or L flags */
/* if they were used. */
/* */
/*****************************************************************************/
static void _sset_arg(_SFIELD *sfield, va_list *_ap, char *tmpbuf)
{
/*------------------------------------------------------------------------*/
/* Local variables */
/*------------------------------------------------------------------------*/
int base;
/*------------------------------------------------------------------------*/
/* Do the assignment only if the result string has a length greater than */
/* zero, and the '*' flag was not used */
/*------------------------------------------------------------------------*/
if (tmpbuf[0] != '\0' && !_STCHK(sfield, _SFSTAR))
switch(sfield->conv)
{
case 'i' :
case 'd' : base = (sfield->conv == 'd') ? 10 : 0;
switch(_STCHK(sfield, (_MFH | _MFL | _MFLL)))
{
case _MFH : *(va_arg(*_ap, short int*)) =
(short int)strtol(tmpbuf, NULL,
base);
break;
case _MFL : *(va_arg(*_ap, long int*)) =
strtol(tmpbuf, NULL, base);
break;
#ifdef LLONG_MAX
case _MFLL : *(va_arg(*_ap, long long int*)) =
strtoll(tmpbuf, NULL, base);
break;
#endif
default : *(va_arg(*_ap, int*)) =
(int)strtol(tmpbuf, NULL, base);
break;
}
break;
/*---------------------------------------------------------------------*/
/* Suppress "conversion from integer to smaller pointer" warning for */
/* the %p case. */
/*---------------------------------------------------------------------*/
#pragma DIAGNOSTIC_SUPPRESS(1107)
case 'p' : *(va_arg(*_ap, void **))=(void *)strtoul(tmpbuf, NULL, 16);
break;
#pragma DIAGNOSTIC_RESET(1107)
case 'x' :
case 'u' :
case 'o' : base = (sfield->conv == 'u') ? 10 :
(sfield->conv == 'x') ? 16 : 8;
switch(_STCHK(sfield, (_MFH | _MFL | _MFLL)))
{
case _MFH : *(va_arg(*_ap, unsigned short int*))=
(unsigned short int)strtoul(tmpbuf,
NULL, base);
break;
case _MFL : *(va_arg(*_ap, unsigned long int*)) =
strtoul(tmpbuf, NULL, base);
break;
#ifdef LLONG_MAX
case _MFLL: *(va_arg(*_ap, unsigned long long int*)) =
strtoull(tmpbuf, NULL, base);
break;
#endif
default : *(va_arg(*_ap, unsigned int*)) =
(unsigned int)strtoul(tmpbuf, NULL,
base);
break;
}
break;
case 'e' :
case 'f' :
case 'g' :
case 'E' :
case 'G' : switch(_STCHK(sfield, (_MFL | _MFLD)))
{
case _MFL : *(va_arg(*_ap, double*))=
strtod(tmpbuf, NULL);
break;
case _MFLD: *(va_arg(*_ap, long double*)) =
strtold(tmpbuf, NULL);
break;
default : *(va_arg(*_ap, float*)) =
(float)strtod(tmpbuf, NULL);
break;
}
break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -