📄 xscanf_f.c
字号:
int which_pointer;
/*---------------------------------------------------------------*/
/* Set curr_ptr to the appropriate value. */
/*---------------------------------------------------------------*/
if (store)
{
if (value == DEFAULT_VALUE)
{
which_pointer = U_INT;
curr_ptr = va_arg(args, unsigned int *);
}
else if (value == l_VALUE)
{
which_pointer = U_LONG_INT;
curr_ptr = va_arg(args, unsigned long *);
}
else if (value == h_VALUE)
{
which_pointer = U_SHORT_INT;
curr_ptr = va_arg(args, unsigned short *);
}
++vars_assigned;
}
else
{
which_pointer = INT;
curr_ptr = &UnusedInt;
}
c_i = ignore_plus(stream, s, &index, &count, c_i);
/*---------------------------------------------------------------*/
/* If c_i is 0, ignore the leading 0x or 0X if ther is one. */
/*---------------------------------------------------------------*/
if (c_i == '0')
{
++count;
c_i = get_char(stream, s, &index);
if (c_i == 'x' || c_i == 'X')
{
++count;
c_i = get_char(stream, s, &index);
}
}
/*---------------------------------------------------------------*/
/* Get the actual number, as a sequence of digits. */
/*---------------------------------------------------------------*/
count = get_num(stream, s, &index, c_i, count, 16, curr_ptr,
width, _PLUS, which_pointer);
state = 0;
break;
}
/*-----------------------------------------------------------------*/
/* State 14 handles the '[' specifier, the scanset. */
/*-----------------------------------------------------------------*/
case 14:
{
int neg = FALSE, size = 0, cnt = 0;
char *scanset, *c_ptr, *curr_ptr;
/*---------------------------------------------------------------*/
/* Check for 'not' flag. */
/*---------------------------------------------------------------*/
if (*format == '^')
{
++format;
neg = TRUE;
}
/*---------------------------------------------------------------*/
/* Beginning of the scanset. */
/*---------------------------------------------------------------*/
scanset = (char *)format;
if (*format == ']')
{
++format;
++size;
}
for (; *format != ']'; ++format, ++size)
{
/*-------------------------------------------------------------*/
/* If the NULL character is specified in format, stop. */
/*-------------------------------------------------------------*/
if (!(*format))
return vars_assigned ? vars_assigned : EOF;
}
/*---------------------------------------------------------------*/
/* Set curr_ptr to the appropriate value. */
/*---------------------------------------------------------------*/
if (store)
curr_ptr = va_arg(args, char *);
for (; cnt < width || !width; ++curr_ptr, ++cnt, ++count)
{
c_i = get_char(stream, s, &index);
/*-------------------------------------------------------------*/
/* Read in width chrs or, if not mentioned, till end of input. */
/*-------------------------------------------------------------*/
if (c_i != '\0')
{
c_ptr = memchr(scanset, c_i, size);
/*-----------------------------------------------------------*/
/* If the input character doesn't match the scanset, stop. */
/*-----------------------------------------------------------*/
if ((neg && c_ptr) || (!neg && !c_ptr))
break;
if (store)
*curr_ptr = c_i;
}
else
break;
}
/*---------------------------------------------------------------*/
/* String must end with a NULL character. */
/*---------------------------------------------------------------*/
if (store)
{
*curr_ptr = '\0';
++vars_assigned;
}
state = 0;
break;
}
/*-----------------------------------------------------------------*/
/* State 15 handles the 'n' specifier. */
/*-----------------------------------------------------------------*/
case 15:
{
int *curr_ptr;
/*---------------------------------------------------------------*/
/* Set curr_ptr to the appropriate value. */
/*---------------------------------------------------------------*/
if (store)
{
curr_ptr = va_arg(args, int *);
*curr_ptr = count;
}
state = 0;
break;
}
/*-----------------------------------------------------------------*/
/* State 16 handles the 'c' specifier. */
/*-----------------------------------------------------------------*/
case 16:
{
int cnt = 0;
char *curr_ptr;
/*---------------------------------------------------------------*/
/* Set curr_ptr to the appropriate value. */
/*---------------------------------------------------------------*/
if (store)
{
curr_ptr = va_arg(args, char *);
++vars_assigned;
}
/*---------------------------------------------------------------*/
/* Read in at least one character. */
/*---------------------------------------------------------------*/
width = width ? width : 1;
for (; cnt < width; ++cnt, ++count)
{
c = get_char(stream, s, &index);
if (store)
*curr_ptr = c;
}
state = 0;
break;
}
/*-----------------------------------------------------------------*/
/* State 17 handles the 'e', 'f', 'g', 'E', and 'G' specifiers. */
/*-----------------------------------------------------------------*/
case 17:
{
long double *curr_ptr_ld;
double *curr_ptr_d;
float *curr_ptr_f;
int which_pointer, initial_count = count - 1, decimal = 0, exp = 0;
int divide = 10, exp_sign;
/*---------------------------------------------------------------*/
/* Set curr_ptr to the appropriate value. */
/*---------------------------------------------------------------*/
if (store)
{
if (value == DEFAULT_VALUE)
{
which_pointer = FLOAT;
curr_ptr_f = va_arg(args, float *);
}
else if(value == l_VALUE)
{
which_pointer = DOUBLE;
curr_ptr_d = va_arg(args, double *);
}
else if (value == L_VALUE)
{
which_pointer = LONG_DOUBLE;
curr_ptr_ld = va_arg(args, long double *);
}
++vars_assigned;
}
/*---------------------------------------------------------------*/
/* Get the sign correctly. */
/*---------------------------------------------------------------*/
plus = get_sign(stream, s, &index, &c_i, &count);
for (;;)
{
/*-------------------------------------------------------------*/
/* If c_i is a digit, decide whether it's before or after */
/* decimal point. */
/*-------------------------------------------------------------*/
if (isdigit(c_i))
{
/*-----------------------------------------------------------*/
/* If decimal is non-zero, add the decimal value. */
/*-----------------------------------------------------------*/
if (decimal)
{
if (store)
{
if (which_pointer == FLOAT)
*curr_ptr_f += ((float) (c_i - '0')) / (float) divide;
else if (which_pointer == DOUBLE)
*curr_ptr_d += ((double) (c_i - '0')) / (double) divide;
else
*curr_ptr_ld += ((long double) (c_i - '0')) /
(long double) divide;
}
divide *= 10;
}
/*-----------------------------------------------------------*/
/* Else add the integral value. */
/*-----------------------------------------------------------*/
else
if (store)
{
if (which_pointer == FLOAT)
*curr_ptr_f = 10 * (*curr_ptr_f) + c_i - '0';
else if (which_pointer == DOUBLE)
*curr_ptr_d = 10 * (*curr_ptr_d) + c_i - '0';
else
*curr_ptr_ld = 10 * (*curr_ptr_ld) + c_i - '0';
}
/*-----------------------------------------------------------*/
/* If we went past allocated width for this number, stop. */
/*-----------------------------------------------------------*/
if (width && (count - initial_count >= width))
break;
c_i = get_char(stream, s, &index);
++count;
}
/*-------------------------------------------------------------*/
/* Else if c_i is '.', reached the decimal point. */
/*-------------------------------------------------------------*/
else if (c_i == '.')
{
/*-----------------------------------------------------------*/
/* Set decimal. */
/*-----------------------------------------------------------*/
decimal = 1;
/*-----------------------------------------------------------*/
/* If we went past allocated width for this number, stop. */
/*-----------------------------------------------------------*/
if (width && (count - initial_count >= width))
break;
c_i = get_char(stream, s, &index);
++count;
}
/*-------------------------------------------------------------*/
/* Else if c_i is 'e' or 'E', get the exponent. */
/*-------------------------------------------------------------*/
else if (c_i == 'E' || c_i == 'e')
{
/*-----------------------------------------------------------*/
/* If we went past allocated width for this number, stop. */
/*-----------------------------------------------------------*/
if (width && (count - initial_count >= width))
break;
c_i = get_char(stream, s, &index);
++count;
/*-----------------------------------------------------------*/
/* Get the exponent sign. */
/*-----------------------------------------------------------*/
exp_sign = get_sign(stream, s, &index, &c_i, &count);
for (; isdigit(c_i); ++count)
{
/*---------------------------------------------------------*/
/* Get the exponent value. */
/*---------------------------------------------------------*/
exp = 10 * exp + c_i - '0';
if (width && (count - initial_count >= width))
break;
c_i = get_char(stream, s, &index);
}
/*-----------------------------------------------------------*/
/* If exponent is negative, get the exponent sign. */
/*-----------------------------------------------------------*/
if (exp_sign == _MINUS)
exp = -exp;
break;
}
else
break;
}
/*---------------------------------------------------------------*/
/* Set the sign correctly. */
/*---------------------------------------------------------------*/
if ((plus == _MINUS) && store)
{
if (which_pointer == FLOAT)
*curr_ptr_f = - (*curr_ptr_f);
else if (which_pointer == DOUBLE)
*curr_ptr_d = - (*curr_ptr_d);
else
*curr_ptr_ld = - (*curr_ptr_ld);
}
/*---------------------------------------------------------------*/
/* Multiply by the exponent. */
/*---------------------------------------------------------------*/
if (exp && store)
{
if (which_pointer == FLOAT)
*curr_ptr_f *= (float) pow(10, exp);
else if (which_pointer == DOUBLE)
*curr_ptr_d *= pow(10, exp);
else
*curr_ptr_ld *= (long double) pow(10, exp);
}
state = 0;
break;
}
default:
break;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -