📄 input.c
字号:
int __cdecl _tinput_l(FILE* stream, const _TUCHAR* format, _locale_t plocinfo, va_list arglist)
#else /* _SECURE_SCANF */
int __cdecl _tinput_s_l(FILE* stream, const _TUCHAR* format, _locale_t plocinfo, va_list arglist)
#endif /* _SECURE_SCANF */
#endif /* CPRFLAG */
#endif /* _SAFECRT_IMPL */
{
_TCHAR floatstring[_CVTBUFSIZE + 1];
_TCHAR *pFloatStr=floatstring;
size_t nFloatStrUsed=0;
size_t nFloatStrSz=sizeof(floatstring)/sizeof(floatstring[0]);
int malloc_FloatStrFlag=0;
unsigned long number; /* temp hold-value */
#if ALLOC_TABLE
char *table = NULL; /* which chars allowed for %[] */
int malloc_flag = 0; /* is "table" allocated on the heap? */
#else /* ALLOC_TABLE */
char AsciiTable[TABLESIZE];
char *table = AsciiTable;
#endif /* ALLOC_TABLE */
unsigned __int64 num64; /* temp for 64-bit integers */
void *pointer=NULL; /* points to user data receptacle */
void *start; /* indicate non-empty string */
#ifndef _UNICODE
wchar_t wctemp=L'\0';
#endif /* _UNICODE */
_TUCHAR *scanptr; /* for building "table" data */
REG2 _TINT ch = 0;
int charcount; /* total number of chars read */
REG1 int comchr; /* holds designator type */
int count; /* return value. # of assignments */
int started; /* indicate good number */
int width; /* width of field */
int widthset; /* user has specified width */
#ifdef _SECURE_SCANF
size_t array_width = 0;
size_t original_array_width = 0;
int enomem = 0;
int format_error = FALSE;
#endif /* _SECURE_SCANF */
/* Neither coerceshort nor farone are need for the 386 */
char done_flag; /* general purpose loop monitor */
char longone; /* 0 = SHORT, 1 = LONG, 2 = L_DOUBLE */
int integer64; /* 1 for 64-bit integer, 0 otherwise */
signed char widechar; /* -1 = char, 0 = ????, 1 = wchar_t */
char reject; /* %[^ABC] instead of %[ABC] */
char negative; /* flag for '-' detected */
char suppress; /* don't assign anything */
char match; /* flag: !0 if any fields matched */
va_list arglistsave; /* save arglist value */
char fl_wchar_arg; /* flags wide char/string argument */
_TCHAR decimal;
_TUCHAR rngch;
_TUCHAR last;
_TUCHAR prevchar;
_TCHAR tch;
_VALIDATE_RETURN( (format != NULL), EINVAL, EOF);
#ifndef CPRFLAG
_VALIDATE_RETURN( (stream != NULL), EINVAL, EOF);
#ifndef _UNICODE
_VALIDATE_STREAM_ANSI_RETURN(stream, EINVAL, EOF);
#endif /* _UNICODE */
#endif /* CPRFLAG */
#ifndef _SAFECRT_IMPL
_LocaleUpdate _loc_update(plocinfo);
#endif /* _SAFECRT_IMPL */
/*
count = # fields assigned
charcount = # chars read
match = flag indicating if any fields were matched
[Note that we need both count and match. For example, a field
may match a format but have assignments suppressed. In this case,
match will get set, but 'count' will still equal 0. We need to
distinguish 'match vs no-match' when terminating due to EOF.]
*/
count = charcount = match = 0;
while (*format) {
if (_istspace((_TUCHAR)*format)) {
UN_INC(EAT_WHITE()); /* put first non-space char back */
do {
tch = *++format;
} while (_istspace((_TUCHAR)tch));
continue;
}
if (_T('%') == *format && _T('%') != *(format + 1)) {
number = 0;
prevchar = 0;
width = widthset = started = 0;
#ifdef _SECURE_SCANF
original_array_width = array_width = 0;
enomem = 0;
#endif /* _SECURE_SCANF */
fl_wchar_arg = done_flag = suppress = negative = reject = 0;
widechar = 0;
longone = 1;
integer64 = 0;
while (!done_flag) {
comchr = *++format;
if (_ISDIGIT((_TUCHAR)comchr)) {
++widthset;
width = MUL10(width) + (comchr - _T('0'));
} else
switch (comchr) {
case _T('F') :
case _T('N') : /* no way to push NEAR in large model */
break; /* NEAR is default in small model */
case _T('h') :
/* set longone to 0 */
--longone;
--widechar; /* set widechar = -1 */
break;
case _T('I'):
if ( (*(format + 1) == _T('6')) &&
(*(format + 2) == _T('4')) )
{
format += 2;
++integer64;
num64 = 0;
break;
}
else if ( (*(format + 1) == _T('3')) &&
(*(format + 2) == _T('2')) )
{
format += 2;
break;
}
else if ( (*(format + 1) == _T('d')) ||
(*(format + 1) == _T('i')) ||
(*(format + 1) == _T('o')) ||
(*(format + 1) == _T('x')) ||
(*(format + 1) == _T('X')) )
{
if (sizeof(void*) == sizeof(__int64))
{
++integer64;
num64 = 0;
}
break;
}
if (sizeof(void*) == sizeof(__int64))
{
++integer64;
num64 = 0;
}
goto DEFAULT_LABEL;
case _T('L') :
/* ++longone; */
++longone;
break;
case _T('l') :
if (*(format + 1) == _T('l'))
{
++format;
#ifdef LONGLONG_IS_INT64
++integer64;
num64 = 0;
break;
#else /* LONGLONG_IS_INT64 */
++longone;
/* NOBREAK */
#endif /* LONGLONG_IS_INT64 */
}
else
{
++longone;
/* NOBREAK */
}
case _T('w') :
++widechar; /* set widechar = 1 */
break;
case _T('*') :
++suppress;
break;
default:
DEFAULT_LABEL:
++done_flag;
break;
}
}
if (!suppress) {
arglistsave = arglist;
pointer = va_arg(arglist,void *);
} else {
pointer = NULL; // doesn't matter what value we use here - we're only using it as a flag
}
done_flag = 0;
if (!widechar) { /* use case if not explicitly specified */
if ((*format == _T('S')) || (*format == _T('C')))
#ifdef _UNICODE
--widechar;
else
++widechar;
#else /* _UNICODE */
++widechar;
else
--widechar;
#endif /* _UNICODE */
}
/* switch to lowercase to allow %E,%G, and to
keep the switch table small */
comchr = *format | (_T('a') - _T('A'));
if (_T('n') != comchr)
if (_T('c') != comchr && LEFT_BRACKET != comchr)
ch = EAT_WHITE();
else
ch = INC();
if (_T('n') != comchr)
{
if (_TEOF == ch)
goto error_return;
}
if (!widthset || width) {
#ifdef _SECURE_SCANF
if(!suppress && (comchr == _T('c') || comchr == _T('s') || comchr == LEFT_BRACKET)) {
arglist = arglistsave;
/* Reinitialize pointer to point to the array to which we write the input */
pointer = va_arg(arglist, void*);
arglistsave = arglist;
/* Get the next argument - size of the array in characters */
#ifdef _WIN64
original_array_width = array_width = (size_t)(va_arg(arglist, unsigned int));
#else /* _WIN64 */
original_array_width = array_width = va_arg(arglist, size_t);
#endif /* _WIN64 */
if(array_width < 1) {
if (widechar > 0)
*(wchar_t UNALIGNED *)pointer = L'\0';
else
*(char *)pointer = '\0';
errno = ENOMEM;
goto error_return;
}
}
#endif /* _SECURE_SCANF */
switch(comchr) {
case _T('c'):
/* case _T('C'): */
if (!widthset) {
++widthset;
++width;
}
if (widechar > 0)
fl_wchar_arg++;
goto scanit;
case _T('s'):
/* case _T('S'): */
if(widechar > 0)
fl_wchar_arg++;
goto scanit;
case LEFT_BRACKET : /* scanset */
if (widechar>0)
fl_wchar_arg++;
scanptr = (_TUCHAR *)(++format);
if (_T('^') == *scanptr) {
++scanptr;
--reject; /* set reject to 255 */
}
/* Allocate "table" on first %[] spec */
#if ALLOC_TABLE
if (table == NULL) {
table = (char*)_malloc_crt(TABLESIZE);
if ( table == NULL)
goto error_return;
malloc_flag = 1;
}
#endif /* ALLOC_TABLE */
memset(table, 0, TABLESIZE);
if (LEFT_BRACKET == comchr)
if (_T(']') == *scanptr) {
prevchar = _T(']');
++scanptr;
table[ _T(']') >> 3] = 1 << (_T(']') & 7);
}
while (_T(']') != *scanptr) {
rngch = *scanptr++;
if (_T('-') != rngch ||
!prevchar || /* first char */
_T(']') == *scanptr) /* last char */
table[(prevchar = rngch) >> 3] |= 1 << (rngch & 7);
else { /* handle a-z type set */
rngch = *scanptr++; /* get end of range */
if (prevchar < rngch) /* %[a-z] */
last = rngch;
else { /* %[z-a] */
last = prevchar;
prevchar = rngch;
}
/* last could be 0xFF, so we handle it at the end of the for loop */
for (rngch = prevchar; rngch < last; ++rngch)
{
table[rngch >> 3] |= 1 << (rngch & 7);
}
table[last >> 3] |= 1 << (last & 7);
prevchar = 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -