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

📄 vfscanf.c

📁 标准c库代码,可以应用于各个系统提供了大量的基本函数
💻 C
📖 第 1 页 / 共 2 页
字号:
	      n = p - p0;	      if (n == 0)		goto match_failure;	      *p = 0;	      nassigned++;	    }	  nread += n;	  break;	case CT_STRING:	  /* like CCL, but zero-length string OK, & no NOSKIP */	  if (width == 0)	    width = ~0;	  if (flags & SUPPRESS)	    {	      n = 0;	      while (!isspace (*fp->_p))		{		  n++, fp->_r--, fp->_p++;		  if (--width == 0)		    break;		  if (BufferEmpty)		    break;		}	      nread += n;	    }	  else	    {	      p0 = p = va_arg (ap, char *);	      while (!isspace (*fp->_p))		{		  fp->_r--;		  *p++ = *fp->_p++;		  if (--width == 0)		    break;		  if (BufferEmpty)		    break;		}	      *p = 0;	      nread += p - p0;	      nassigned++;	    }	  continue;	case CT_INT:	  /* scan an integer as if by strtol/strtoul */#ifdef hardway	  if (width == 0 || width > sizeof (buf) - 1)	    width = sizeof (buf) - 1;#else	  /* size_t is unsigned, hence this optimisation */	  if (--width > sizeof (buf) - 2)	    width = sizeof (buf) - 2;	  width++;#endif	  flags |= SIGNOK | NDIGITS | NZDIGITS;	  for (p = buf; width; width--)	    {	      c = *fp->_p;	      /*	       * Switch on the character; `goto ok' if we	       * accept it as a part of number.	       */	      switch (c)		{		  /*		   * The digit 0 is always legal, but is special.		   * For %i conversions, if no digits (zero or nonzero)		   * have been scanned (only signs), we will have base==0.		   * In that case, we should set it to 8 and enable 0x		   * prefixing. Also, if we have not scanned zero digits		   * before this, do not turn off prefixing (someone else		   * will turn it off if we have scanned any nonzero digits).		   */		case '0':		  if (base == 0)		    {		      base = 8;		      flags |= PFXOK;		    }		  if (flags & NZDIGITS)		    flags &= ~(SIGNOK | NZDIGITS | NDIGITS);		  else		    flags &= ~(SIGNOK | PFXOK | NDIGITS);		  goto ok;		  /* 1 through 7 always legal */		case '1':		case '2':		case '3':		case '4':		case '5':		case '6':		case '7':		  base = basefix[base];		  flags &= ~(SIGNOK | PFXOK | NDIGITS);		  goto ok;		  /* digits 8 and 9 ok iff decimal or hex */		case '8':		case '9':		  base = basefix[base];		  if (base <= 8)		    break;	/* not legal here */		  flags &= ~(SIGNOK | PFXOK | NDIGITS);		  goto ok;		  /* letters ok iff hex */		case 'A':		case 'B':		case 'C':		case 'D':		case 'E':		case 'F':		case 'a':		case 'b':		case 'c':		case 'd':		case 'e':		case 'f':		  /* no need to fix base here */		  if (base <= 10)		    break;	/* not legal here */		  flags &= ~(SIGNOK | PFXOK | NDIGITS);		  goto ok;		  /* sign ok only as first character */		case '+':		case '-':		  if (flags & SIGNOK)		    {		      flags &= ~SIGNOK;		      goto ok;		    }		  break;		  /* x ok iff flag still set & 2nd char */		case 'x':		case 'X':		  if (flags & PFXOK && p == buf + 1)		    {		      base = 16;/* if %i */		      flags &= ~PFXOK;		      goto ok;		    }		  break;		}	      /*	       * If we got here, c is not a legal character	       * for a number.  Stop accumulating digits.	       */	      break;	    ok:	      /*	       * c is legal: store it and look at the next.	       */	      *p++ = c;	      if (--fp->_r > 0)		fp->_p++;	      else#ifndef CYGNUS_NEC	      if (__srefill (fp))#endif		break;		/* EOF */	    }	  /*	   * If we had only a sign, it is no good; push back the sign.	   * If the number ends in `x', it was [sign] '0' 'x', so push back	   * the x and treat it as [sign] '0'.	   */	  if (flags & NDIGITS)	    {	      if (p > buf)		_CAST_VOID ungetc (*(u_char *)-- p, fp);	      goto match_failure;	    }	  c = ((u_char *) p)[-1];	  if (c == 'x' || c == 'X')	    {	      --p;	      /*(void)*/ ungetc (c, fp);	    }	  if ((flags & SUPPRESS) == 0)	    {	      u_long res;	      *p = 0;	      res = (*ccfn) (buf, (char **) NULL, base);	      if (flags & POINTER)		*(va_arg (ap, _PTR *)) = (_PTR) res;	      else if (flags & SHORT)		{		  sp = va_arg (ap, short *);		  *sp = res;		}	      else if (flags & LONG)		{		  lp = va_arg (ap, long *);		  *lp = res;		}	      else		{		  ip = va_arg (ap, int *);		  *ip = res;		}	      nassigned++;	    }	  nread += p - buf;	  break;#ifdef FLOATING_POINT	case CT_FLOAT:	  /* scan a floating point number as if by strtod */#ifdef hardway	  if (width == 0 || width > sizeof (buf) - 1)	    width = sizeof (buf) - 1;#else	  /* size_t is unsigned, hence this optimisation */	  if (--width > sizeof (buf) - 2)	    width = sizeof (buf) - 2;	  width++;#endif	  flags |= SIGNOK | NDIGITS | DPTOK | EXPOK;	  for (p = buf; width; width--)	    {	      c = *fp->_p;	      /*	       * This code mimicks the integer conversion	       * code, but is much simpler.	       */	      switch (c)		{		case '0':		case '1':		case '2':		case '3':		case '4':		case '5':		case '6':		case '7':		case '8':		case '9':		  flags &= ~(SIGNOK | NDIGITS);		  goto fok;		case '+':		case '-':		  if (flags & SIGNOK)		    {		      flags &= ~SIGNOK;		      goto fok;		    }		  break;		case '.':		  if (flags & DPTOK)		    {		      flags &= ~(SIGNOK | DPTOK);		      goto fok;		    }		  break;		case 'e':		case 'E':		  /* no exponent without some digits */		  if ((flags & (NDIGITS | EXPOK)) == EXPOK)		    {		      flags =			(flags & ~(EXPOK | DPTOK)) |			SIGNOK | NDIGITS;		      goto fok;		    }		  break;		}	      break;	    fok:	      *p++ = c;	      if (--fp->_r > 0)		fp->_p++;	      else#ifndef CYGNUS_NEC	      if (__srefill (fp))#endif		break;		/* EOF */	    }	  /*	   * If no digits, might be missing exponent digits	   * (just give back the exponent) or might be missing	   * regular digits, but had sign and/or decimal point.	   */	  if (flags & NDIGITS)	    {	      if (flags & EXPOK)		{		  /* no digits at all */		  while (p > buf)		    ungetc (*(u_char *)-- p, fp);		  goto match_failure;		}	      /* just a bad exponent (e and maybe sign) */	      c = *(u_char *)-- p;	      if (c != 'e' && c != 'E')		{		  _CAST_VOID ungetc (c, fp);	/* sign */		  c = *(u_char *)-- p;		}	      _CAST_VOID ungetc (c, fp);	    }	  if ((flags & SUPPRESS) == 0)	    {	      double res;	      *p = 0;	      res = atof (buf);	      if (flags & LONG)		{		  dp = va_arg (ap, double *);		  *dp = res;		}	      else if (flags & LONGDBL)		{		  ldp = va_arg (ap, _LONG_DOUBLE *);		  *ldp = res;		}	      else		{		  flp = va_arg (ap, float *);		  *flp = res;		}	      nassigned++;	    }	  nread += p - buf;	  break;#endif /* FLOATING_POINT */	}    }input_failure:  return nassigned ? nassigned : -1;match_failure:  return nassigned;}/* * Fill in the given table from the scanset at the given format * (just after `[').  Return a pointer to the character past the * closing `]'.  The table has a 1 wherever characters should be * considered part of the scanset. *//*static*/u_char *__sccl (tab, fmt)     register char *tab;     register u_char *fmt;{  register int c, n, v;  /* first `clear' the whole table */  c = *fmt++;			/* first char hat => negated scanset */  if (c == '^')    {      v = 1;			/* default => accept */      c = *fmt++;		/* get new first char */    }  else    v = 0;			/* default => reject */  /* should probably use memset here */  for (n = 0; n < 256; n++)    tab[n] = v;  if (c == 0)    return fmt - 1;		/* format ended before closing ] */  /*   * Now set the entries corresponding to the actual scanset to the   * opposite of the above.   *   * The first character may be ']' (or '-') without being special; the   * last character may be '-'.   */  v = 1 - v;  for (;;)    {      tab[c] = v;		/* take character c */    doswitch:      n = *fmt++;		/* and examine the next */      switch (n)	{	case 0:		/* format ended too soon */	  return fmt - 1;	case '-':	  /*	   * A scanset of the form [01+-] is defined as `the digit 0, the	   * digit 1, the character +, the character -', but the effect of a	   * scanset such as [a-zA-Z0-9] is implementation defined.  The V7	   * Unix scanf treats `a-z' as `the letters a through z', but treats	   * `a-a' as `the letter a, the character -, and the letter a'.	   *	   * For compatibility, the `-' is not considerd to define a range if	   * the character following it is either a close bracket (required by	   * ANSI) or is not numerically greater than the character we just	   * stored in the table (c).	   */	  n = *fmt;	  if (n == ']' || n < c)	    {	      c = '-';	      break;		/* resume the for(;;) */	    }	  fmt++;	  do	    {			/* fill in the range */	      tab[++c] = v;	    }	  while (c < n);#if 1			/* XXX another disgusting compatibility hack */	  /*	   * Alas, the V7 Unix scanf also treats formats such	   * as [a-c-e] as `the letters a through e'. This too	   * is permitted by the standard....	   */	  goto doswitch;#else	  c = *fmt++;	  if (c == 0)	    return fmt - 1;	  if (c == ']')	    return fmt;#endif	  break;	case ']':		/* end of scanset */	  return fmt;	default:		/* just another character */	  c = n;	  break;	}    }  /* NOTREACHED */}

⌨️ 快捷键说明

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