📄 vfscanf.c
字号:
if (width <= MAX_POS_ARGS) { N = width - 1; is_pos_arg = 1; width = 0; goto again; } rptr->_errno = EINVAL; goto input_failure;#endif /* !_NO_POS_ARGS */ /* * Conversions. Those marked `compat' are for * 4.[123]BSD compatibility. * * (According to ANSI, E and X formats are supposed to * the same as e and x. Sorry about that.) */ case 'D': /* compat */ flags |= LONG; /* FALLTHROUGH */ case 'd': c = CT_INT; ccfn = (u_long (*)())_strtol_r; base = 10; break; case 'i': c = CT_INT; ccfn = (u_long (*)())_strtol_r; base = 0; break; case 'O': /* compat */ flags |= LONG; /* FALLTHROUGH */ case 'o': c = CT_INT; ccfn = _strtoul_r; base = 8; break; case 'u': c = CT_INT; ccfn = _strtoul_r; base = 10; break; case 'X': case 'x': flags |= PFXOK; /* enable 0x prefixing */ c = CT_INT; ccfn = _strtoul_r; base = 16; break;#ifdef FLOATING_POINT# ifdef _WANT_IO_C99_FORMATS case 'a': case 'A': case 'F':# endif case 'E': case 'G': case 'e': case 'f': case 'g': c = CT_FLOAT; break;#endif#ifdef _WANT_IO_C99_FORMATS case 'S': flags |= LONG; /* FALLTHROUGH */#endif case 's': c = CT_STRING; break; case '[': fmt = __sccl (ccltab, fmt); flags |= NOSKIP; c = CT_CCL; break;#ifdef _WANT_IO_C99_FORMATS case 'C': flags |= LONG; /* FALLTHROUGH */#endif case 'c': flags |= NOSKIP; c = CT_CHAR; break; case 'p': /* pointer format is like hex */ flags |= POINTER | PFXOK; c = CT_INT; ccfn = _strtoul_r; base = 16; break; case 'n': if (flags & SUPPRESS) /* ??? */ continue;#ifdef _WANT_IO_C99_FORMATS if (flags & CHAR) { cp = GET_ARG (N, ap, char *); *cp = nread; } else#endif if (flags & SHORT) { sp = GET_ARG (N, ap, short *); *sp = nread; } else if (flags & LONG) { lp = GET_ARG (N, ap, long *); *lp = nread; }#ifndef _NO_LONGLONG else if (flags & LONGDBL) { llp = GET_ARG (N, ap, long long*); *llp = nread; }#endif else { ip = GET_ARG (N, ap, int *); *ip = nread; } continue; /* * Disgusting backwards compatibility hacks. XXX */ case '\0': /* compat */ _funlockfile (fp); return EOF; default: /* compat */ if (isupper (c)) flags |= LONG; c = CT_INT; ccfn = (u_long (*)())_strtol_r; base = 10; break; } /* * We have a conversion that requires input. */ if (BufferEmpty) goto input_failure; /* * Consume leading white space, except for formats that * suppress this. */ if ((flags & NOSKIP) == 0) { while (isspace (*fp->_p)) { nread++; if (--fp->_r > 0) fp->_p++; else if (__srefill_r (rptr, fp)) goto input_failure; } /* * Note that there is at least one character in the * buffer, so conversions that do not set NOSKIP ca * no longer result in an input failure. */ } /* * Do the conversion. */ switch (c) { case CT_CHAR: /* scan arbitrary characters (sets NOSKIP) */ if (width == 0) width = 1; if (flags & LONG) { if ((flags & SUPPRESS) == 0) wcp = GET_ARG (N, ap, wchar_t *); else wcp = NULL; n = 0; while (width != 0) { if (n == MB_CUR_MAX) goto input_failure; buf[n++] = *fp->_p; fp->_r -= 1; fp->_p += 1; memset ((_PTR)&state, '\0', sizeof (mbstate_t)); if ((mbslen = _mbrtowc_r (rptr, wcp, buf, n, &state)) == (size_t)-1) goto input_failure; /* Invalid sequence */ if (mbslen == 0 && !(flags & SUPPRESS)) *wcp = L'\0'; if (mbslen != (size_t)-2) /* Incomplete sequence */ { nread += n; width -= 1; if (!(flags & SUPPRESS)) wcp += 1; n = 0; } if (BufferEmpty) { if (n != 0) goto input_failure; break; } } if (!(flags & SUPPRESS)) nassigned++; } else if (flags & SUPPRESS) { size_t sum = 0; for (;;) { if ((n = fp->_r) < (int)width) { sum += n; width -= n; fp->_p += n; if (__srefill_r (rptr, fp)) { if (sum == 0) goto input_failure; break; } } else { sum += width; fp->_r -= width; fp->_p += width; break; } } nread += sum; } else { size_t r = fread ((_PTR) GET_ARG (N, ap, char *), 1, width, fp); if (r == 0) goto input_failure; nread += r; nassigned++; } break; case CT_CCL: /* scan a (nonempty) character class (sets NOSKIP) */ if (width == 0) width = ~0; /* `infinity' */ /* take only those things in the class */ if (flags & SUPPRESS) { n = 0; while (ccltab[*fp->_p]) { n++, fp->_r--, fp->_p++; if (--width == 0) break; if (BufferEmpty) { if (n == 0) goto input_failure; break; } } if (n == 0) goto match_failure; } else { p0 = p = GET_ARG (N, ap, char *); while (ccltab[*fp->_p]) { fp->_r--; *p++ = *fp->_p++; if (--width == 0) break; if (BufferEmpty) { if (p == p0) goto input_failure; break; } } 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 = (size_t)~0; if (flags & LONG) { /* Process %S and %ls placeholders */ if ((flags & SUPPRESS) == 0) wcp = GET_ARG (N, ap, wchar_t *); else wcp = &wc; n = 0; while (!isspace (*fp->_p) && width != 0) { if (n == MB_CUR_MAX) goto input_failure; buf[n++] = *fp->_p; fp->_r -= 1; fp->_p += 1; memset ((_PTR)&state, '\0', sizeof (mbstate_t)); if ((mbslen = _mbrtowc_r (rptr, wcp, buf, n, &state)) == (size_t)-1) goto input_failure; if (mbslen == 0) *wcp = L'\0'; if (mbslen != (size_t)-2) /* Incomplete sequence */ { if (iswspace(*wcp)) { while (n != 0) _ungetc_r (rptr, (unsigned char) buf[--n], fp); break; } nread += n; width -= 1; if ((flags & SUPPRESS) == 0) wcp += 1; n = 0; } if (BufferEmpty) { if (n != 0) goto input_failure; break; } } if (!(flags & SUPPRESS)) { *wcp = L'\0'; nassigned++; } } else 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 = GET_ARG (N, 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 */ unsigned width_left = 0; int skips = 0;#ifdef hardway if (width == 0 || width > sizeof (buf) - 1)#else /* size_t is unsigned, hence this optimisation */ if (width - 1 > sizeof (buf) - 2)#endif { width_left = width - (sizeof (buf) - 1); width = sizeof (buf) - 1; } flags |= SIGNOK | NDIGITS | NZDIGITS | NNZDIGITS; 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 (! (flags & NNZDIGITS)) goto ok; if (base == 0) { base = 8; flags |= PFXOK; } if (flags & NZDIGITS) { flags &= ~(SIGNOK | NZDIGITS | NDIGITS); goto ok; } flags &= ~(SIGNOK | PFXOK | NDIGITS); if (width_left) { width_left--; width++; } ++skips; goto skip; /* 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 | NNZDIGITS); 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 | NNZDIGITS); goto ok; /* letters ok iff hex */ case 'A':
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -