⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 input.c

📁 C标准库源代码
💻 C
📖 第 1 页 / 共 5 页
字号:

#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 */


#ifdef _UNICODE
static int __cdecl _winput(FILE *, const unsigned char *, 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 char sbrackset[] = " \t-\n]"; /* use range-style list, cl68 swaps \n to \r*/


static char cbrackset[] = "]";



/***
*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)

static int __cdecl _winput (
    FILE *stream,
    const unsigned char *format,
    va_list arglist
    )
#else  /* defined (_UNICODE) */

int __cdecl _input (
    FILE *stream,
    const unsigned char *format,
    va_list arglist
    )
#endif  /* defined (_UNICODE) */

{
    char table[ASCII];                  /* which chars allowed for %[], %s   */
#ifndef _UNICODE
    char floatstring[CVTBUFSIZE + 1];   /* ASCII buffer for floats           */
#else  /* _UNICODE */
    wchar_t floatstring[CVTBUFSIZE + 1];
#endif  /* _UNICODE */

    unsigned long number;               /* temp hold-value                   */
    unsigned __int64 num64;             /* temp for 64-bit integers          */
    void *pointer;                      /* points to user data receptacle    */
    void *start;                        /* indicate non-empty string         */

    unsigned char *scanptr;             /* for building "table" data         */

#ifdef _UNICODE
REG2 wchar_t ch;
#else  /* _UNICODE */
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 */

    unsigned char rngch;                /* used while scanning range         */

    char done_flag;                     /* general purpose loop monitor      */
    unsigned char last;                 /* also for %[a-z]                   */
    char longone;                       /* 0 = SHORT, 1 = LONG, 2 = L_DOUBLE */
    int integer64;                      /* 1 for 64-bit integer, 0 otherwise */
    char negative;                      /* flag for '-' detected             */
    unsigned char prevchar;             /* for %[a-z]                        */
    char reject;                        /* %[^ABC] instead of %[ABC]         */
    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 wdecimal;                   /* wide version of decimal point     */
    wchar_t *wptr;                      /* pointer traverses wide floatstring*/
#endif  /* _UNICODE */

    int _tflag = 0;

    _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 (isspace((int)*format)) {

            UN_INC(EAT_WHITE()); /* put first non-space char back */

            while ((isspace)(*++format)); /* NULL */
            /* careful: isspace macro may evaluate argument more than once! */

        }

        if ('%' == *format) {

            number = width = widthset = started = done_flag =

            /* ints are the same size as longs and all pointers are 'near' for
               the 386 */

            suppress = negative = reject = prevchar = 0;
            longone = 1;

            integer64 = 0;

            fl_wchar_arg = 0;

            while (!done_flag) {

                comchr = *++format;
                if (isdigit(comchr)) {
                    ++widthset;
                    width = MUL10(width) + (comchr - '0');
                } else
                    switch (comchr) {
                        case 'F':
                        case 'N':   /* no way to push NEAR in large model */
                            break;  /* NEAR is default in small model */
                        case 'h':
                            /* set longone to 0 */
                            --longone;
                            break;

            case _T('I'):
                if ( (*(format + 1) == _T('6')) &&
                     (*(format + 2) == _T('4')) )
                {
                    format += 2;
                    ++integer64;
                    num64 = 0;
                    break;
                }
                goto DEFAULT_LABEL;

            case 'L':
                            ++longone;
                                    /* NOBREAK */
                        case 'l':
                            ++longone;
                            break;
                        case '*':
                            ++suppress;
                            break;

                        default:
DEFAULT_LABEL:
                            ++done_flag;
                            break;
                    }
            }

            if (!suppress) {
                arglistsave = arglist;
                pointer = va_arg(arglist,void *);
            }

            done_flag = 0;

            /* switch to lowercase to allow %E,%G, and to
               keep the switch table small */

            comchr = *format | ('a' - 'A');

            /*
             *  Generic string handling support:  %tc, %ts accept
             *  either chars or wide-chars depending on _tflag.
             *  _tflag == 1 means wide-chars.
             */
            if (comchr == 't') {
                if (_tflag == 1)
                    comchr = 'w';
                else
                    comchr = *(++format);
            }

            if ('n' != comchr)
                if ('w' == comchr) {
                    fl_wchar_arg = 1;
                    comchr = *++format;
                    if (comchr == 'c')
                        ch = INC();
                    else if (comchr == 's')
                        ch = EAT_WHITE();
                    else
                        goto error_return; /* not 'wc' or 'ws' */
                } else
                if ('c' != comchr && LEFT_BRACKET != comchr)
                    ch = EAT_WHITE();
                else
                    ch = INC();

            if (!widthset || width) {

                switch(comchr) {

                    case 'c':
                        if (!widthset) {
                            ++widthset;
                            ++width;
                        }
                        scanptr = cbrackset;
                        --reject; /* set reject to 255 */
                        goto scanit2;

                    case 's':
                        scanptr = sbrackset;
                        --reject; /* set reject to 255 */
                        goto scanit2;

                    case LEFT_BRACKET :   /* scanset */
                        scanptr = (char *)(++format);

                        if ('^' == *scanptr) {
                            ++scanptr;
                            --reject; /* set reject to 255 */
                        }


scanit2:
                        memset(table, 0, ASCII);


                        if (LEFT_BRACKET == comchr)
                            if (']' == *scanptr) {
                                prevchar = ']';
                                ++scanptr;

                                table[ ']' >> 3] = 1 << (']' & 7);

                            }

                        while (']' != *scanptr) {

                            rngch = *scanptr++;

                            if ('-' != rngch ||
                                 !prevchar ||           /* first char */
                                 ']' == *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;
                                }
                                for (rngch = prevchar; rngch <= last; ++rngch)
                                    table[rngch >> 3] |= 1 << (rngch & 7);

                                prevchar = 0;

                            }
                        }


                        if (!*scanptr)
                            goto error_return;      /* trunc'd format string */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -