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

📄 xscanf.c

📁 ATMEL单片机可用的文件系统源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/***********************************************************************/
/*                                                                     */
/*   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 + -