?? input.c
字號:
/***
*input.c - C formatted input, used by scanf, etc.
*
* Copyright (c) 1987-1997, Microsoft Corporation. All rights reserved.
*
*Purpose:
* defines _input() to do formatted input; called from scanf(),
* etc. functions. This module defines _cscanf() instead when
* CPRFLAG is defined. The file cscanf.c defines that symbol
* and then includes this file in order to implement _cscanf().
*
*******************************************************************************/
#ifdef _WIN32
#define ALLOW_RANGE /* allow "%[a-z]"-style scansets */
/* temporary work-around for compiler without 64-bit support */
#ifndef _INTEGRAL_MAX_BITS
#define _INTEGRAL_MAX_BITS 64
#endif /* _INTEGRAL_MAX_BITS */
#include <cruntime.h>
#include <stdio.h>
#include <ctype.h>
#include <cvt.h>
#include <conio.h>
#include <stdarg.h>
#include <string.h>
#include <internal.h>
#include <fltintrn.h>
#include <mtdll.h>
#include <stdlib.h>
#include <nlsint.h>
#include <dbgint.h>
#ifdef _MBCS
#undef _MBCS
#endif /* _MBCS */
#include <tchar.h>
#define HEXTODEC(chr) _hextodec(chr)
#define LEFT_BRACKET ('[' | ('a' - 'A')) /* 'lowercase' version */
#ifdef _UNICODE
static wchar_t __cdecl _hextodec(wchar_t);
#else /* _UNICODE */
static int __cdecl _hextodec(int);
#endif /* _UNICODE */
/*
* Note: CPRFLAG and _UNICODE cases are currently mutually exclusive.
*/
#ifdef CPRFLAG
#define INC() (++charcount, _inc())
#define UN_INC(chr) (--charcount, _ungetch_lk(chr))
#define EAT_WHITE() _whiteout(&charcount)
static int __cdecl _inc(void);
static int __cdecl _whiteout(int *);
#else /* CPRFLAG */
#define INC() (++charcount, _inc(stream))
#define UN_INC(chr) (--charcount, _un_inc(chr, stream))
#define EAT_WHITE() _whiteout(&charcount, stream)
#ifndef _UNICODE
static int __cdecl _inc(FILE *);
static void __cdecl _un_inc(int, FILE *);
static int __cdecl _whiteout(int *, FILE *);
#else /* _UNICODE */
static wchar_t __cdecl _inc(FILE *);
static void __cdecl _un_inc(wchar_t, FILE *);
static wchar_t __cdecl _whiteout(int *, FILE *);
#endif /* _UNICODE */
#endif /* CPRFLAG */
#ifndef _UNICODE
#define _ISDIGIT(chr) isdigit(chr)
#define _ISXDIGIT(chr) isxdigit(chr)
#else /* _UNICODE */
#define _ISDIGIT(chr) ( !(chr & 0xff00) && isdigit( chr & 0x00ff ) )
#define _ISXDIGIT(chr) ( !(chr & 0xff00) && isxdigit( chr & 0x00ff ) )
#endif /* _UNICODE */
#ifdef _UNICODE
int __cdecl _winput(FILE *, const wchar_t *, va_list);
#endif /* _UNICODE */
#ifdef CPRFLAG
static int __cdecl input(const unsigned char *, va_list);
/***
*int _cscanf(format, arglist) - read formatted input direct from console
*
*Purpose:
* Reads formatted data like scanf, but uses console I/O functions.
*
*Entry:
* char *format - format string to determine data formats
* arglist - list of POINTERS to where to put data
*
*Exit:
* returns number of successfully matched data items (from input)
*
*Exceptions:
*
*******************************************************************************/
int __cdecl _cscanf (
const char *format,
...
)
{
va_list arglist;
va_start(arglist, format);
_ASSERTE(format != NULL);
return input(format,arglist); /* get the input */
}
#endif /* CPRFLAG */
#define ASCII 32 /* # of bytes needed to hold 256 bits */
#define SCAN_SHORT 0 /* also for FLOAT */
#define SCAN_LONG 1 /* also for DOUBLE */
#define SCAN_L_DOUBLE 2 /* only for LONG DOUBLE */
#define SCAN_NEAR 0
#define SCAN_FAR 1
static _TCHAR sbrackset[] = _T(" \t-\r]"); /* use range-style list */
static _TCHAR cbrackset[] = _T("]");
/***
*int _input(stream, format, arglist), static int input(format, arglist)
*
*Purpose:
* get input items (data items or literal matches) from the input stream
* and assign them if appropriate to the items thru the arglist. this
* function is intended for internal library use only, not for the user
*
* The _input entry point is for the normal scanf() functions
* The input entry point is used when compiling for _cscanf() [CPRFLAF
* defined] and is a static function called only by _cscanf() -- reads from
* console.
*
*Entry:
* FILE *stream - file to read from
* char *format - format string to determine the data to read
* arglist - list of pointer to data items
*
*Exit:
* returns number of items assigned and fills in data items
* returns EOF if error or EOF found on stream before 1st data item matched
*
*Exceptions:
*
*******************************************************************************/
#ifdef CPRFLAG
static int __cdecl input (
const unsigned char *format,
va_list arglist
)
#elif defined (_UNICODE)
int __cdecl _winput (
FILE *stream,
const wchar_t *format,
va_list arglist
)
#else /* defined (_UNICODE) */
int __cdecl _input (
FILE *stream,
const unsigned char *format,
va_list arglist
)
#endif /* defined (_UNICODE) */
{
#ifndef _UNICODE
char table[ASCII]; /* which chars allowed for %[], %s */
char floatstring[CVTBUFSIZE + 1]; /* ASCII buffer for floats */
#else /* _UNICODE */
char table[256*ASCII];
wchar_t floatstring[CVTBUFSIZE + 1];
#endif /* _UNICODE */
unsigned long number; /* temp hold-value */
#if _INTEGRAL_MAX_BITS >= 64
unsigned __int64 num64; /* temp for 64-bit integers */
#endif /* _INTEGRAL_MAX_BITS >= 64 */
void *pointer; /* points to user data receptacle */
void *start; /* indicate non-empty string */
#ifdef _UNICODE
wchar_t *scanptr; /* for building "table" data */
REG2 wchar_t ch;
#else /* _UNICODE */
wchar_t wctemp;
unsigned char *scanptr; /* for building "table" data */
REG2 int ch;
#endif /* _UNICODE */
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 */
/* 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 */
#if _INTEGRAL_MAX_BITS >= 64
int integer64; /* 1 for 64-bit integer, 0 otherwise */
#endif /* _INTEGRAL_MAX_BITS >= 64 */
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 */
#ifdef _UNICODE
wchar_t rngch; /* used while scanning range */
wchar_t last; /* also for %[a-z] */
wchar_t prevchar; /* for %[a-z] */
wchar_t wdecimal; /* wide version of decimal point */
wchar_t *wptr; /* pointer traverses wide floatstring*/
#else /* _UNICODE */
unsigned char rngch; /* used while scanning range */
unsigned char last; /* also for %[a-z] */
unsigned char prevchar; /* for %[a-z] */
#endif /* _UNICODE */
_ASSERTE(format != NULL);
#ifndef CPRFLAG
_ASSERTE(stream != NULL);
#endif /* CPRFLAG */
/*
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 */
while ((_istspace)(*++format)); /* NULL */
/* careful: isspace macro may evaluate argument more than once! */
}
if (_T('%') == *format) {
number = 0;
prevchar = 0;
width = widthset = started = 0;
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;
#if _INTEGRAL_MAX_BITS >= 64
case _T('I'):
if ( (*(format + 1) == _T('6')) &&
(*(format + 2) == _T('4')) )
{
format += 2;
++integer64;
num64 = 0;
break;
}
goto DEFAULT_LABEL;
#endif /* _INTEGRAL_MAX_BITS >= 64 */
case _T('L') :
/* ++longone; */
++longone;
break;
case _T('l') :
++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 *);
}
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)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -