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

📄 prscanf.c

📁 Netscape NSPR库源码
💻 C
📖 第 1 页 / 共 2 页
字号:
static PRStatusGetFloat(ScanfState *state){    char buf[FMAX + 1], *p;    int ch;    PRBool seenDigit = PR_FALSE;    if (state->width == 0 || state->width > FMAX) {        state->width = FMAX;    }    p = buf;    GET_IF_WITHIN_WIDTH(state, ch);    if (WITHIN_WIDTH(state) && (ch == '+' || ch == '-')) {        *p++ = ch;        GET_IF_WITHIN_WIDTH(state, ch);    }    while (WITHIN_WIDTH(state) && isdigit(ch)) {        *p++ = ch;        GET_IF_WITHIN_WIDTH(state, ch);        seenDigit = PR_TRUE;    }    if (WITHIN_WIDTH(state) && ch == DECIMAL_POINT) {        *p++ = ch;        GET_IF_WITHIN_WIDTH(state, ch);        while (WITHIN_WIDTH(state) && isdigit(ch)) {            *p++ = ch;            GET_IF_WITHIN_WIDTH(state, ch);            seenDigit = PR_TRUE;        }    }    /*     * This is not robust.  For example, "1.2e+" would confuse     * the code below to read 'e' and '+', only to realize that     * it should have stopped at "1.2".  But we can't push back     * more than one character, so there is nothing I can do.     */    /* Parse exponent */    if (WITHIN_WIDTH(state) && (ch == 'e' || ch == 'E') && seenDigit) {        *p++ = ch;        GET_IF_WITHIN_WIDTH(state, ch);        if (WITHIN_WIDTH(state) && (ch == '+' || ch == '-')) {            *p++ = ch;            GET_IF_WITHIN_WIDTH(state, ch);        }        while (WITHIN_WIDTH(state) && isdigit(ch)) {            *p++ = ch;            GET_IF_WITHIN_WIDTH(state, ch);        }    }    if (WITHIN_WIDTH(state)) {        UNGET(state, ch);    }    if (!seenDigit) {        return PR_FAILURE;    }    *p = '\0';    if (state->assign) {        PRFloat64 dval = PR_strtod(buf, NULL);        state->converted = PR_TRUE;        if (state->sizeSpec == _PR_size_l) {            *va_arg(state->ap, PRFloat64 *) = dval;        } else if (state->sizeSpec == _PR_size_L) {#if defined(OSF1) || defined(IRIX)            *va_arg(state->ap, double *) = dval;#else            *va_arg(state->ap, long double *) = dval;#endif        } else {            *va_arg(state->ap, float *) = (float) dval;        }    }    return PR_SUCCESS;}/* * Convert, and return the end of the conversion spec. * Return NULL on error. */static const char *Convert(ScanfState *state, const char *fmt){    const char *cPtr;    int ch;    char *cArg = NULL;    state->converted = PR_FALSE;    cPtr = fmt;    if (*cPtr != 'c' && *cPtr != 'n' && *cPtr != '[') {        do {            ch = GET(state);        } while (isspace(ch));        UNGET(state, ch);    }    switch (*cPtr) {        case 'c':            if (state->assign) {                cArg = va_arg(state->ap, char *);            }            if (state->width == 0) {                state->width = 1;            }            for (; state->width > 0; state->width--) {                ch = GET(state);                if (ch == EOF) {                    return NULL;                } else if (state->assign) {                    *cArg++ = ch;                }            }            if (state->assign) {                state->converted = PR_TRUE;            }            break;        case 'p':        case 'd': case 'i': case 'o':        case 'u': case 'x': case 'X':            if (GetInt(state, *cPtr) == PR_FAILURE) {                return NULL;            }            break;        case 'e': case 'E': case 'f':        case 'g': case 'G':            if (GetFloat(state) == PR_FAILURE) {                return NULL;            }            break;        case 'n':            /* do not consume any input */            if (state->assign) {                switch (state->sizeSpec) {                    case _PR_size_none:                        *va_arg(state->ap, PRIntn *) = state->nChar;                        break;                    case _PR_size_h:                        *va_arg(state->ap, PRInt16 *) = state->nChar;                        break;                    case _PR_size_l:                        *va_arg(state->ap, PRInt32 *) = state->nChar;                        break;                    case _PR_size_ll:                        LL_I2L(*va_arg(state->ap, PRInt64 *), state->nChar);                        break;                    default:                        PR_ASSERT(0);                }            }            break;        case 's':            if (state->width == 0) {                state->width = INT_MAX;            }            if (state->assign) {                cArg = va_arg(state->ap, char *);            }            for (; state->width > 0; state->width--) {                ch = GET(state);                if ((ch == EOF) || isspace(ch)) {                    UNGET(state, ch);                    break;                }                if (state->assign) {                    *cArg++ = ch;                }            }            if (state->assign) {                *cArg = '\0';                state->converted = PR_TRUE;            }            break;        case '%':            ch = GET(state);            if (ch != '%') {                UNGET(state, ch);                return NULL;            }            break;        case '[':            {                PRBool complement = PR_FALSE;                const char *closeBracket;                size_t n;                if (*++cPtr == '^') {                    complement = PR_TRUE;                    cPtr++;                }                closeBracket = strchr(*cPtr == ']' ? cPtr + 1 : cPtr, ']');                if (closeBracket == NULL) {                    return NULL;                }                n = closeBracket - cPtr;                if (state->width == 0) {                    state->width = INT_MAX;                }                if (state->assign) {                    cArg = va_arg(state->ap, char *);                }                for (; state->width > 0; state->width--) {                    ch = GET(state);                    if ((ch == EOF)                             || (!complement && !memchr(cPtr, ch, n))                            || (complement && memchr(cPtr, ch, n))) {                        UNGET(state, ch);                        break;                    }                    if (state->assign) {                        *cArg++ = ch;                    }                }                if (state->assign) {                    *cArg = '\0';                    state->converted = PR_TRUE;                }                cPtr = closeBracket;            }            break;        default:            return NULL;    }    return cPtr;}static PRInt32DoScanf(ScanfState *state, const char *fmt){    PRInt32 nConverted = 0;    const char *cPtr;    int ch;    state->nChar = 0;    cPtr = fmt;    while (1) {        if (isspace(*cPtr)) {            /* white space: skip */            do {                cPtr++;            } while (isspace(*cPtr));            do {                ch = GET(state);            } while (isspace(ch));            UNGET(state, ch);        } else if (*cPtr == '%') {            /* format spec: convert */            cPtr++;            state->assign = PR_TRUE;            if (*cPtr == '*') {                cPtr++;                state->assign = PR_FALSE;            }            for (state->width = 0; isdigit(*cPtr); cPtr++) {                state->width = state->width * 10 + *cPtr - '0';            }            state->sizeSpec = _PR_size_none;            if (*cPtr == 'h') {                cPtr++;                state->sizeSpec = _PR_size_h;            } else if (*cPtr == 'l') {                cPtr++;                if (*cPtr == 'l') {                    cPtr++;                    state->sizeSpec = _PR_size_ll;                } else {                    state->sizeSpec = _PR_size_l;                }            } else if (*cPtr == 'L') {                cPtr++;                state->sizeSpec = _PR_size_L;            }            cPtr = Convert(state, cPtr);            if (cPtr == NULL) {                return (nConverted > 0 ? nConverted : EOF);            }            if (state->converted) {                nConverted++;            }            cPtr++;        } else {            /* others: must match */            if (*cPtr == '\0') {                return nConverted;            }            ch = GET(state);            if (ch != *cPtr) {                UNGET(state, ch);                return nConverted;            }            cPtr++;        }    }}static intStringGetChar(void *stream){    char *cPtr = *((char **) stream);    if (*cPtr == '\0') {        return EOF;    } else {        *((char **) stream) = cPtr + 1;        return *cPtr;    }}static voidStringUngetChar(void *stream, int ch){    char *cPtr = *((char **) stream);    if (ch != EOF) {        *((char **) stream) = cPtr - 1;    }}PR_IMPLEMENT(PRInt32)PR_sscanf(const char *buf, const char *fmt, ...){    PRInt32 rv;    ScanfState state;    state.get = &StringGetChar;    state.unget = &StringUngetChar;    state.stream = (void *) &buf;    va_start(state.ap, fmt);    rv = DoScanf(&state, fmt);    va_end(state.ap);    return rv;}

⌨️ 快捷键说明

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