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

📄 scanf.c

📁 linux下用PCMCIA无线网卡虚拟无线AP的程序源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Modified by Manuel Novoa III       Mar 13, 2001 * * The vfscanf routine was completely rewritten to add features and remove * bugs.  The function __strtold, based on my strtod code in stdlib, was * added to provide floating point support for the scanf functions. * * So far they pass the test cases from glibc-2.1.3, except in two instances. * In one case, the test appears to be broken.  The other case is something * I need to research further.  This version of scanf assumes it can only * peek one character ahead.  Apparently, glibc looks further.  The difference * can be seen when parsing a floating point value in the character * sequence "100ergs".  glibc is able to back up before the 'e' and return * a value of 100, whereas this scanf reports a bad match with the stream * pointer at 'r'.  A similar situation can also happen when parsing hex * values prefixed by 0x or 0X; a failure would occur for "0xg".  In order to * fix this, I need to rework the "ungetc" machinery in stdio.c again. * I do have one reference though, that seems to imply scanf has a single * character of lookahead. * * May 20, 2001 * * Quote from ANSI/ISO C99 standard: * *    fscanf pushes back at most one input character onto the input stream. *    Therefore, some sequences that are acceptable to strtod, strtol, etc., *    are unacceptable to fscanf. * * So uClibc's *scanf functions conform to the standard, and glibc's * implementation doesn't for the "100ergs" case mentioned above. */#include <stdlib.h>#include <unistd.h>#define __USE_ISOC99#include <stdio.h>#include <ctype.h>#include <string.h>#include <stdarg.h>#ifdef L_scanf#ifdef __STDC__int scanf(const char *fmt, ...)#elseint scanf(fmt, va_alist)__const char *fmt;va_dcl#endif{	va_list ptr;	int rv;	va_start(ptr, fmt);	rv = vfscanf(stdin, fmt, ptr);	va_end(ptr);	return rv;}#endif#ifdef L_sscanf#ifdef __STDC__int sscanf(const char *sp, const char *fmt, ...)#elseint sscanf(sp, fmt, va_alist)__const char *sp;__const char *fmt;va_dcl#endif{	FILE string[1] = {		{0, (unsigned char *) ((unsigned) -1), 0, 0, (char *) ((unsigned) -1),		 0, -1, _IOFBF}	};	va_list ptr;	int rv;	string->bufpos = (unsigned char *) ((void *) sp);	va_start(ptr, fmt);	rv = vfscanf(string, fmt, ptr);	va_end(ptr);	return rv;}#endif#ifdef L_fscanf#ifdef __STDC__int fscanf(FILE * fp, const char *fmt, ...)#elseint fscanf(fp, fmt, va_alist)FILE *fp;__const char *fmt;va_dcl#endif{	va_list ptr;	int rv;	va_start(ptr, fmt);	rv = vfscanf(fp, fmt, ptr);	va_end(ptr);	return rv;}#endif#ifdef L_vscanfint vscanf(fmt, ap)__const char *fmt;va_list ap;{	return vfscanf(stdin, fmt, ap);}#endif#ifdef L_vsscanfint vsscanf(__const char *sp, __const char *fmt, va_list ap){	FILE string[1] = {		{0, (unsigned char *) ((unsigned) -1), 0, 0, (char *) ((unsigned) -1),		 0, -1, _IOFBF}	};	string->bufpos = (unsigned char *) sp;	return vfscanf(string, fmt, ap);}#endif#ifdef L_vfscanf#include <assert.h>#include <ctype.h>#include <limits.h>static int valid_digit(char c, char base){	if (base == 16) {		return isxdigit(c);	} else {		return (isdigit(c) && (c < '0' + base));	}}extern unsigned long long_strto_ll(const char *str, char **endptr, int base, int uflag);extern unsigned long_strto_l(const char *str, char **endptr, int base, int uflag);struct scan_cookie {	FILE *fp;	int nread;	int width;	int width_flag;	int ungot_char;	int ungot_flag;};#ifdef __UCLIBC_HAS_LONG_LONG__static const char qual[] = "hl" /* "jtz" */ "Lq";/* char = -2, short = -1, int = 0, long = 1, long long = 2 */static const char qsz[] = { -1, 1,           2, 2 };#elsestatic const char qual[] = "hl" /* "jtz" */;static const char qsz[] = { -1, 1,         };#endif#ifdef __UCLIBC_HAS_FLOATS__static int __strtold(long double *ld, struct scan_cookie *sc);						   /*01234567890123456 */static const char spec[]  = "%n[csoupxXidfeEgG";#elsestatic const char spec[]  = "%n[csoupxXid";#endif/* radix[i] <-> spec[i+5]     o   u   p   x   X  i   d */static const char radix[] = { 8, 10, 16, 16, 16, 0, 10 };static void init_scan_cookie(struct scan_cookie *sc, FILE *fp){	sc->fp = fp;	sc->nread = 0;	sc->width_flag = 0;	sc->ungot_flag = 0;}static int scan_getc_nw(struct scan_cookie *sc){	if (sc->ungot_flag == 0) {		sc->ungot_char = getc(sc->fp);	} else {		sc->ungot_flag = 0;	}	if (sc->ungot_char > 0) {		++sc->nread;	}	sc->width_flag = 0;	return sc->ungot_char;}static int scan_getc(struct scan_cookie *sc){	if (sc->ungot_flag == 0) {		sc->ungot_char = getc(sc->fp);	}	sc->width_flag = 1;	if (--sc->width < 0) {		sc->ungot_flag = 1;		return 0;	}	sc->ungot_flag = 0;	if (sc->ungot_char > 0) {		++sc->nread;	}	return sc->ungot_char;}static void scan_ungetc(struct scan_cookie *sc){	if (sc->ungot_flag != 0) {		assert(sc->width < 0);		return;	}	if (sc->width_flag) {		++sc->width;	}	sc->ungot_flag = 1;	if (sc->ungot_char > 0) {	/* not EOF or EOS */		--sc->nread;	}}static void kill_scan_cookie(struct scan_cookie *sc){	if (sc->ungot_flag) {		ungetc(sc->ungot_char,sc->fp);	}}int vfscanf(fp, format, ap)FILE *fp;const char *format;va_list ap;{#ifdef __UCLIBC_HAS_LONG_LONG__#define STRTO_L_(s,e,b,u) _strto_ll(s,e,b,u)#define MAX_DIGITS 64#define UV_TYPE unsigned long long#define V_TYPE long long#else#define STRTO_L_(s,e,b,u) _strto_l(s,e,b,u)#define MAX_DIGITS 32#define UV_TYPE unsigned long#define V_TYPE long#endif#ifdef __UCLIBC_HAS_FLOATS__	long double ld;#endif	UV_TYPE uv;	struct scan_cookie sc;	unsigned const char *fmt;	const char *p;	unsigned char *b;	void *vp;	int cc, i, cnt;	signed char lval;	unsigned char store, usflag, base, invert, r0, r1;	unsigned char buf[MAX_DIGITS+2];	unsigned char scanset[UCHAR_MAX + 1];	init_scan_cookie(&sc,fp);	fmt = (unsigned const char *) format;	cnt = 0;	while (*fmt) {		store = 1;		lval = 0;		sc.width = INT_MAX;		if (*fmt == '%') {		/* Conversion specification. */			++fmt;			if (*fmt == '*') {	/* Suppress assignment. */				store = 0;				++fmt;			}			for (i = 0 ; isdigit(*fmt) ; sc.width = i) {				i = (i * 10) + (*fmt++ - '0'); /* Get specified width. */			}			for (i = 0 ; i < sizeof(qual) ; i++) { /* Optional qualifier. */				if (qual[i] == *fmt) {					++fmt;					lval += qsz[i];					if ((i < 2) && (qual[i] == *fmt)) {	/* Double h or l. */						++fmt;						lval += qsz[i];					}					break;				}			}			for (p = spec ; *p ; p++) {	/* Process format specifier. */				if (*fmt != *p) continue;				if (p-spec < 1) { /* % - match a '%'*/					goto matchchar;				}				if (p-spec < 2) { /* n - store number of chars read */					*(va_arg(ap, int *)) = sc.nread;					scan_getc_nw(&sc);					goto nextfmt;				}				if (p-spec > 3) { /* skip white space if not c or [ */					while (isspace(scan_getc_nw(&sc)))						{}					scan_ungetc(&sc);				}				if (p-spec < 5) { /* [,c,s - string conversions */					invert = 0;					if (*p == 'c') {						invert = 1;						if (sc.width == INT_MAX) {							sc.width = 1;						}					}					for (i=0 ; i<= UCHAR_MAX ; i++) {						scanset[i] = ((*p == 's') ? (isspace(i) == 0) : 0);					}					if (*p == '[') { /* need to build a scanset */						if (*++fmt == '^') {							invert = 1;							++fmt;						}						if (*fmt == ']') {							scanset[(int)']'] = 1;							++fmt;						}						r0 = 0;						while (*fmt && *fmt !=']') { /* build scanset */							if ((*fmt == '-') && r0 && (fmt[1] != ']')) {								/* range */								++fmt;								if (*fmt < r0) {									r1 = r0;									r0 = *fmt;								} else {									r1 = *fmt;								}								for (i=r0 ; i<= r1 ; i++) {									scanset[i] = 1;								}								r0 = 0;							} else {								r0 = *fmt;								scanset[r0] = 1;							}							++fmt;						}						if (!*fmt) { /* format string exhausted! */							goto done;						}

⌨️ 快捷键说明

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