📄 input.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
/***
*input.c - C formatted input, used by scanf, etc.
*
*
*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().
*
*******************************************************************************/
#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
#include <cruntime.h>
#include <crtmisc.h>
#include <stdio.h>
#include <crtctype.h>
#include <stdarg.h>
#include <string.h>
#include <internal.h>
#include <fltintrn.h>
#include <mtdll.h>
#include <stdlib.h>
#include <dbgint.h>
#ifdef _MBCS /* always want either Unicode or SBCS for tchar.h */
#undef _MBCS
#endif
#include <crttchar.h>
#ifdef CRT_UNICODE
#define _eof_char WEOF
#else
#define _eof_char EOF
#endif
#undef iswspace
__inline static int iswspace(wchar_t i) {
if (((i)==0x20) || ((i)>=0x09 && (i)<=0x0D))
return 1;
return 0;
}
#undef isspace
__inline static int isspace(char i)
{
if(((i)==0x20) || ((i)>=0x09 && (i)<=0x0D))
return 1;
else
return 0;
}
#define HEXTODEC(chr) _hextodec(chr)
#define LEFT_BRACKET ('[' | ('a' - 'A')) /* 'lowercase' version */
#ifdef CRT_UNICODE
static wchar_t __cdecl _hextodec(wchar_t);
#else
static int __cdecl _hextodec(int);
#endif
/*
* Note: CPRFLAG and CRT_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
#define INC() (++charcount, _inc(stream))
#define UN_INC(chr) (--charcount, _un_inc(chr, stream))
#define EAT_WHITE() _whiteout(&charcount, stream)
#ifndef CRT_UNICODE
static int __cdecl _inc(FILEX *);
static void __cdecl _un_inc(int, FILEX *);
static int __cdecl _whiteout(int *, FILEX *);
#else
static wchar_t __cdecl _inc(FILEX *);
static void __cdecl _un_inc(wchar_t, FILEX *);
static wchar_t __cdecl _whiteout(int *, FILEX *);
#endif /* CRT_UNICODE */
#endif /* CPRFLAG */
#ifndef CRT_UNICODE
#define _ISDIGIT(chr) isdigit(chr)
#define _ISXDIGIT(chr) isxdigit(chr)
#else
#define _ISDIGIT(chr) ( !(chr & 0xff00) && isdigit( chr & 0x00ff ) )
#define _ISXDIGIT(chr) ( !(chr & 0xff00) && isxdigit( chr & 0x00ff ) )
#endif
#ifdef CRT_UNICODE
int __cdecl _winput(FILEX *, const wchar_t *, va_list);
#endif
#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
#ifdef ALLOW_RANGE
static const CRT__TCHAR sbrackset[] = CRT_T(" \t-\r]"); /* use range-style list */
#else
static const CRT__TCHAR sbrackset[] = CRT_T(" \t\n\v\f\r]"); /* chars defined by isspace() */
#endif
static const CRT__TCHAR cbrackset[] = CRT_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:
* FILEX *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(CRT_UNICODE)
int __cdecl _winput (
FILEX *stream,
const wchar_t *format,
va_list arglist
)
#else
int __cdecl _input (
FILEX *stream,
const unsigned char *format,
va_list arglist
)
#endif
{
#ifndef CRT_UNICODE
char table[ASCII]; /* which chars allowed for %[], %s */
char floatstring[CVTBUFSIZE + 1]; /* ASCII buffer for floats */
#else
char table[256*ASCII];
wchar_t floatstring[CVTBUFSIZE + 1];
#endif
unsigned long number; /* temp hold-value */
#if _INTEGRAL_MAX_BITS >= 64
unsigned __int64 num64; /* temp for 64-bit integers */
#endif
void *pointer; /* points to user data receptacle */
void *start; /* indicate non-empty string */
#ifdef CRT_UNICODE
wchar_t *scanptr; /* for building "table" data */
REG2 wchar_t ch = 0;
#else
wchar_t wctemp;
unsigned char *scanptr; /* for building "table" data */
REG2 int ch = 0;
#endif
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
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 CRT_UNICODE
#ifdef ALLOW_RANGE
wchar_t rngch; /* used while scanning range */
#endif
wchar_t last; /* also for %[a-z] */
wchar_t prevchar; /* for %[a-z] */
wchar_t *wptr; /* pointer traverses wide floatstring*/
#else
#ifdef ALLOW_RANGE
unsigned char rngch; /* used while scanning range */
#endif
unsigned char last; /* also for %[a-z] */
unsigned char prevchar; /* for %[a-z] */
#endif
_ASSERTE(format != NULL);
#ifndef CPRFLAG
_ASSERTE(stream != NULL);
#endif
/*
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((CRT__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 (CRT_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((CRT__TUCHAR)comchr)) {
++widthset;
width = MUL10(width) + (comchr - CRT_T('0'));
} else
switch (comchr) {
case CRT_T('F') :
case CRT_T('N') : /* no way to push NEAR in large model */
break; /* NEAR is default in small model */
case CRT_T('h') :
/* set longone to 0 */
--longone;
--widechar; /* set widechar = -1 */
break;
#if _INTEGRAL_MAX_BITS >= 64
case CRT_T('I'):
if ( (*(format + 1) == CRT_T('6')) &&
(*(format + 2) == CRT_T('4')) )
{
format += 2;
++integer64;
num64 = 0;
break;
}
goto DEFAULT_LABEL;
#endif
case CRT_T('L') :
/* ++longone; */
++longone;
break;
case CRT_T('l') :
++longone;
/* NOBREAK */
case CRT_T('w') :
++widechar; /* set widechar = 1 */
break;
case CRT_T('*') :
++suppress;
break;
default:
DEFAULT_LABEL:
++done_flag;
break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -