📄 xscanf.c
字号:
/***********************************************************************/
/* */
/* Module: xscanf.c */
/* Release: 2004.5 */
/* Version: 2003.5 */
/* Purpose: Implements fscanf(), scanf(), sscanf() helper function */
/* for integer-only runtime library "runlib.a" */
/* */
/*---------------------------------------------------------------------*/
/* */
/* Copyright 2004, Blunk Microsystems */
/* ALL RIGHTS RESERVED */
/* */
/* Licensees have the non-exclusive right to use, modify, or extract */
/* this computer program for software development at a single site. */
/* This program may be resold or disseminated in executable format */
/* only. The source code may not be redistributed or resold. */
/* */
/***********************************************************************/
#include "stdiop.h"
/***********************************************************************/
/* Macro Definitions */
/***********************************************************************/
#define INT 1
#define SHORT_INT 3
#define LONG_INT 5
#define U_INT 12
#define U_SHORT_INT 14
#define U_LONG_INT 16
#define SIGNED 1
/***********************************************************************/
/* Global Variables */
/***********************************************************************/
static int UnusedInt;
/***********************************************************************/
/* Local Function Definitions */
/***********************************************************************/
/***********************************************************************/
/* put_char: Put a character back onto the input stream */
/* */
/* Inputs: stream = pointer to file control block */
/* index = index into string */
/* c = char to be place back on the input stream */
/* */
/***********************************************************************/
static void put_char(FILE *stream, int *index, char c)
{
/*-------------------------------------------------------------------*/
/* If not EOF or full, save in control block. */
/*-------------------------------------------------------------------*/
if (stream)
{
if ((c != EOF) && !stream->hold_char)
stream->hold_char = c;
}
else
--(*index);
}
/***********************************************************************/
/* get_char: Read a character from the input */
/* */
/* Inputs: stream = pointer to file control block */
/* s = input string */
/* index = index into string */
/* */
/* Returns: the last character read from the input */
/* */
/***********************************************************************/
static char get_char(FILE *stream, const char *s, int *index)
{
ui8 rv;
/*-------------------------------------------------------------------*/
/* If stream is valid, use it as input, else use string s. */
/*-------------------------------------------------------------------*/
if (stream)
{
/*-----------------------------------------------------------------*/
/* Read either pushed-back character or new input character. */
/*-----------------------------------------------------------------*/
if (stream->hold_char)
{
rv = (ui8)stream->hold_char;
stream->hold_char = 0;
}
else
{
if (stream->read(stream, &rv, 1) != 1)
return (char)-1;
}
}
else
{
/*-----------------------------------------------------------------*/
/* Read in character from an input string and increment string. */
/*-----------------------------------------------------------------*/
rv = (ui8)s[*index];
++(*index);
}
return (char)rv;
}
/***********************************************************************/
/* get_num: Read a sequence of characters and convert them into a */
/* number in the specified base */
/* */
/* Inputs: stream = pointer to file control block */
/* s = input string */
/* index = index into string */
/* c = first char read from input */
/* count = number of chars read in so far */
/* base = base for the conversion */
/* value = value in which the coversion is stored */
/* width = maximum number of digits */
/* plus = the sign for value */
/* which_pointer = the type for value */
/* */
/* Returns: number new of characters read so far */
/* */
/***********************************************************************/
static int get_num(FILE *stream, const char *s, int *index, char c,
int count, int base, void *value, int width, int plus,
int which_pointer)
{
int cnt = 0, factor;
long signed_val = 0;
unsigned long unsigned_val = 0;
for (;;)
{
/*-----------------------------------------------------------------*/
/* If we've reached the end of string, put back character. */
/*-----------------------------------------------------------------*/
if (((base == 10) && !isdigit(c)) ||
((base == 8) && !(c >= '0' && c <= '7')) ||
((base == 16) && !isxdigit(c)))
{
while ((isdigit(c) || (base == 16 && isxdigit(c))) &&
(width > cnt || !width))
{
++cnt;
c = get_char(stream, s, index);
}
put_char(stream, index, c);
break;
}
/*-----------------------------------------------------------------*/
/* If we haven't exceeded the width, update value. */
/*-----------------------------------------------------------------*/
if ((width && (width >= cnt)) || !width)
{
if (c <= '9')
factor = c - '0';
else if (c < 'a')
factor = c - 'A' + 10;
else
factor = c - 'a' + 10;
if (which_pointer & SIGNED)
signed_val = base * signed_val + factor;
else
unsigned_val = base * unsigned_val + factor;
}
/*-----------------------------------------------------------------*/
/* Get the next char from the input. */
/*-----------------------------------------------------------------*/
++count;
++cnt;
/*-----------------------------------------------------------------*/
/* If we've got width characters from the input, stop. */
/*-----------------------------------------------------------------*/
if (width <= cnt && width)
{
break;
}
c = get_char(stream, s, index);
}
/*-------------------------------------------------------------------*/
/* If it's a negative number, need to change the sign. */
/*-------------------------------------------------------------------*/
if (!plus)
{
if (which_pointer & SIGNED)
signed_val = -signed_val;
else
unsigned_val = -unsigned_val;
}
/*-------------------------------------------------------------------*/
/* Store the value in the return pointer. */
/*-------------------------------------------------------------------*/
switch (which_pointer)
{
case INT:
case LONG_INT:
*(long *)value = signed_val;
break;
case SHORT_INT:
*(short *)value = (short)signed_val;
break;
case U_INT:
case U_LONG_INT:
*(unsigned long *)value = unsigned_val;
break;
case U_SHORT_INT:
*(unsigned short *)value = (unsigned short)unsigned_val;
break;
}
return count;
}
/***********************************************************************/
/* ignore_plus: Read char from input and one more if first is '+' */
/* */
/* Inputs: st = pointer to file control block */
/* s = input string */
/* i = index into string */
/* cnt = number of chars read in so far */
/* c_i = the sign character */
/* */
/* Returns: last character read from the input */
/* */
/***********************************************************************/
static char ignore_plus(FILE *st, const char *s, int *i, int *cnt,
char c_i)
{
char r_value = c_i;
if (r_value == '+')
{
++(*cnt);
r_value = get_char(st, s, i);
}
return r_value;
}
/***********************************************************************/
/* get_sign: Read char from input and one more if '+' or '-' */
/* */
/* Inputs: stream = pointer to file control block */
/* s = input string */
/* index = index into string */
/* c = last character read from the input */
/* ct = number of chars read in so far */
/* */
/* Returns: the sign, 1 for '+', 0 for '-', default is '+' */
/* */
/***********************************************************************/
static int get_sign(FILE *stream, const char *s, int *index, char *c,
int *ct)
{
int r_value = _PLUS;
/*-------------------------------------------------------------------*/
/* If there is a sign, read in an extra character. */
/*-------------------------------------------------------------------*/
if (*c == '-' || *c == '+')
{
r_value = (*c == '-') ? _MINUS : _PLUS;
++(*ct);
*c = get_char(stream, s, index);
}
return r_value;
}
/***********************************************************************/
/* Global Function Definitions */
/***********************************************************************/
/***********************************************************************/
/* ProcessScanf: Read variable acording to format into args */
/* */
/* Inputs: stream = pointer to file control block */
/* format = string with reading directives */
/* args = arguments in which the values read are stored */
/* s = input string */
/* */
/* Returns: number of successful assignments or EOF */
/* */
/***********************************************************************/
int ProcessScanf(FILE *stream, const char *format, va_list args,
const char *s)
{
int vars_assigned = 0, count = 0, state = 0, index = 0;
char c, c_i;
int width, value, store;
int plus;
for (;;)
{
/*-----------------------------------------------------------------*/
/* Look at the format a character at a time and go to right state. */
/*-----------------------------------------------------------------*/
c = *format;
switch (state)
{
/*-----------------------------------------------------------------*/
/* State 0 reads in chars and goes to right state or terminates. */
/*-----------------------------------------------------------------*/
case 0:
{
++format;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -