?? _scanfi.c
字號:
/*****************************************************************************/
/* _SCANFI.C v2.24 */
/* Copyright (c) 1995-2002 Texas Instruments Incorporated */
/*****************************************************************************/
/*****************************************************************************/
/* This file contains the main routines that all three variations of the */
/* scanf function use. The main function in the file is _scanfi, and */
/* the other functions here are called by it. */
/* */
/* FUNCTIONS: */
/* _scanfi - The main scanf handling routine */
/* _sget_conv - Read the format flags into the _SFIELD pointer sfield*/
/* _sget_scanset - Read in the scanset from the format statement */
/* _sproc_int - Read an integer string into a temporary string */
/* _sproc_float - Read a float string into a temporary string */
/* _sproc_str - Copy a string from the input source to a temporary */
/* string */
/* _sproc_lb - Process the %[ conversion */
/* _sset_arg - Assign the converted value to the next argument */
/*****************************************************************************/
#include <stdio.h>
#include "format.h"
#include <stdarg.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <limits.h>
#ifdef LLONG_MAX
_CODE_ACCESS long long strtoll(const char *_st, char **_endptr, int _base);
_CODE_ACCESS unsigned long long strtoull(const char *_st, char **_endptr,
int _base);
#endif
_CODE_ACCESS long double strtold(const char *st, char **endptr);
static int _sget_conv(char **_format, _SFIELD *sfield);
static int _sget_scanset(_SFIELD *sfield, char **_format);
static int _sproc_int(int w_counter, int (*_inpchar)(void **inp),
void (*_uninpchar)(void **inp, char outchar),
char *tmpptr, char conv, void **inp, int *num_read);
static int _sproc_float(int w_counter, int (*_inpchar)(void **inp),
void (*_uninpchar)(void **inp, char outchar),
char *tmpptr, char conv, void **inp, int *num_read);
static int _sproc_str(int w_counter, int (*_inpchar)(void **inp),
void (*_uninpchar)(void **inp, char outchar),
char *tmpptr, char conv, void **inp, int *num_read);
static int _sproc_lb(int (*_inpchar)(void **inp),
void (*_uninpchar)(void **inp, char outchar),
char *tmpptr, _SFIELD *sfield, void **inp, int *num_read);
static void _sset_arg(_SFIELD *sfield, va_list *_ap, char *tmpbuf);
/*****************************************************************************/
/* _SCANFI - The main scanf handling routine */
/* */
/* This function parses all non-conversion characters in the format */
/* string, passes control to the appropriate function when a '%' is */
/* encountered, then calls _SSET_ARG, which assignes the result to the */
/* next argument. */
/* */
/*****************************************************************************/
int _scanfi(void *inp, const char *_format, va_list _ap,
int (*_chkmbc)(void **inp, char **_format, int *num_read),
int (*_inpchar)(void **inp),
void (*_uninpchar)(void **inp, char outchar))
{
/*------------------------------------------------------------------------*/
/* Local variables */
/*------------------------------------------------------------------------*/
_SFIELD sfield;
char tmpbuf[256],
*tmpptr,
*f_ptr = (char *)_format;
int num_assigned = 0,
inchar,
num_read = 0,
stat = 0;
/*------------------------------------------------------------------------*/
/* If the first character in the format string is a white space character */
/* parse the format string until a non-white space character is found. */
/* Do the same for the input, but put the first non-white space character */
/* back onto the input stream when finished. */
/*------------------------------------------------------------------------*/
if (isspace(*f_ptr))
{
for(;isspace(*f_ptr);f_ptr++);
inchar = _inpchar(&inp);
if(inchar == EOF) return EOF;
num_read++;
for(;isspace(inchar); inchar = _inpchar(&inp), num_read++);
_uninpchar(&inp, inchar);
num_read--;
if(inchar == EOF) return EOF;
}
while(1)
{
/*---------------------------------------------------------------------*/
/* Initialize sfield */
/*---------------------------------------------------------------------*/
memset(&sfield, 0, sizeof(_SFIELD));
sfield.fwidth = -1;
/*---------------------------------------------------------------------*/
/* Call _chkmbc to compare the format string to the input. If a */
/* mismatch occurs, return an EOF, if the end of the format string */
/* is reached, return the number of arguments assigned. Otherwise */
/* a '%' has been encountered, so call _sget_conv to process it. */
/*---------------------------------------------------------------------*/
switch(_chkmbc(&inp, &f_ptr, &num_read))
{
case EOF : return (EOF);
case 0 : return (num_assigned);
case 1 : _sget_conv(&f_ptr, &sfield);
}
tmpptr = tmpbuf;
/*---------------------------------------------------------------------*/
/* Unless the conversion specifier is a [, c, or n, skip to the next */
/* non-white space character in the input. */
/*---------------------------------------------------------------------*/
if (sfield.conv != '[' && sfield.conv != 'c' && sfield.conv != 'n')
{
inchar = _inpchar(&inp);
num_read++;
for(;isspace(inchar); inchar = _inpchar(&inp), num_read++);
_uninpchar(&inp, inchar);
num_read--;
/*---------------------------------------------------------------*/
/* If we've encountered the end of the stream AND we haven't */
/* matched anything yet, return EOF. */
/*---------------------------------------------------------------*/
if(inchar == EOF && num_read == 0) return EOF;
}
else
{
/*---------------------------------------------------------------*/
/* If we've encountered the end of the stream AND we haven't */
/* matched anything yet, return EOF. */
/*---------------------------------------------------------------*/
inchar = _inpchar(&inp);
_uninpchar(&inp, inchar);
if(inchar == EOF && num_read == 0) return EOF;
}
/*---------------------------------------------------------------------*/
/* The flags have been set in sfield, so process the conversion by */
/* calling the appropriate function. */
/*---------------------------------------------------------------------*/
switch(sfield.conv)
{
case 'X' : sfield.conv = 'x';
case 'i' :
case 'p' :
case 'x' :
case 'u' :
case 'o' :
case 'd' : stat = _sproc_int(sfield.fwidth, _inpchar, _uninpchar,
tmpptr, sfield.conv, &inp, &num_read);
break;
case 'f' :
case 'e' :
case 'E' :
case 'g' :
case 'G' : stat = _sproc_float(sfield.fwidth, _inpchar, _uninpchar,
tmpptr, sfield.conv, &inp, &num_read);
break;
case 'c' :
case 's' : {
char *stptr = (sfield.flags & _SFSTAR) ?
NULL : va_arg(_ap, char*);
stat = _sproc_str(sfield.fwidth, _inpchar, _uninpchar,
stptr, sfield.conv, &inp, &num_read);
}
stat = (stat != EOF);
if (!(sfield.flags & _SFSTAR) && stat) num_assigned++;
break;
case '[' : stat = _sproc_lb(_inpchar, _uninpchar, tmpptr, &sfield,
&inp, &num_read);
}
stat = (stat != EOF);
/*---------------------------------------------------------------------*/
/* Now, call the function to handle the actual assignment, or if there */
/* is no assignment to take place, process it here. */
/*---------------------------------------------------------------------*/
switch(sfield.conv)
{
case 'i' :
case 'd' :
case 'x' :
case 'u' :
case 'o' :
case 'p' :
case 'e' :
case 'f' :
case 'g' :
case 'E' :
case 'G' : _sset_arg(&sfield, &_ap, tmpbuf);
if ((!(sfield.flags & _SFSTAR)) && stat) num_assigned++;
break;
case 'n' : if (!(sfield.flags & _SFSTAR))
switch(sfield.flags & (_MFH | _MFL | _MFLL))
{
case _MFH : *(va_arg(_ap, short int*)) =
(short int)num_read;
break;
case _MFL : *(va_arg(_ap, long int*)) =
(long int)num_read;
break;
#ifdef LLONG_MAX
case _MFLL : *(va_arg(_ap, long long int*)) =
(long long int)num_read;
break;
#endif
default : *(va_arg(_ap, int*)) =
num_read;
break;
}
break;
case '%' : inchar = _inpchar(&inp);
if (inchar != '%') return (EOF);
else num_read++;
break;
case '[' : if ((!(sfield.flags & _SFSTAR)) && stat)
{
strcpy(va_arg(_ap, char *), tmpbuf);
num_assigned++;
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -