📄 scanf.c
字号:
* the format suppresses this behavior. */ if (!(flags & SCAN_NOSKIP)) { while (*string != '\0') { sch = *string; if (! isspace((int)sch) ) { break; } string++; } if (*string == '\0') { underflow = 1; goto done; } } /* * Perform the requested scanning operation. */ switch (op) { case 'c': case 's': /* * Scan a string up to width characters or whitespace. */ if (width == 0) { width = (size_t) ~0; } end = string; while (*end != '\0') { sch = *end; if ( isspace( (int)sch ) ) { break; } end++; if (--width == 0) { break; } } if (!(flags & SCAN_SUPPRESS)) { if (numVars && objIndex >= argCount) { break; } else if (numVars) { current = args[objIndex++]; zval_dtor( *current ); ZVAL_STRINGL( *current, string, end-string, 1); } else { add_index_stringl( *return_value, objIndex++, string, end-string, 1); } } string = end; break; case '[': { CharSet cset; if (width == 0) { width = (size_t) ~0; } end = string; format = BuildCharSet(&cset, format); while (*end != '\0') { sch = *end; if (!CharInSet(&cset, (int)sch)) { break; } end++; if (--width == 0) { break; } } ReleaseCharSet(&cset); if (string == end) { /* * Nothing matched the range, stop processing */ goto done; } if (!(flags & SCAN_SUPPRESS)) { if (numVars && objIndex >= argCount) { break; } else if (numVars) { current = args[objIndex++]; zval_dtor( *current ); ZVAL_STRINGL( *current, string, end-string, 1); } else { add_index_stringl(*return_value, objIndex++, string, end-string, 1); } } string = end; break; } /* case 'c': / Scan a single character./ sch = *string; string++; if (!(flags & SCAN_SUPPRESS)) { if (numVars) { char __buf[2]; __buf[0] = sch; __buf[1] = '\0';; current = args[objIndex++]; convert_to_string_ex( current ); ZVAL_STRINGL( *current, __buf, 1, 1); } else { add_index_stringl(*return_value, objIndex++, &sch, 1, 1); } } break; */ case 'i': /* * Scan an unsigned or signed integer. */ /*-cc-*/ buf[0] = '\0'; /*-cc-*/ if ((width == 0) || (width > sizeof(buf) - 1)) { width = sizeof(buf) - 1; } flags |= SCAN_SIGNOK | SCAN_NODIGITS | SCAN_NOZERO; for (end = buf; width > 0; width--) { switch (*string) { /* * The 0 digit has special meaning at the beginning of * a number. If we are unsure of the base, it * indicates that we are in base 8 or base 16 (if it is * followed by an 'x'). */ case '0': /*-cc-*/ if (base == 16) { flags |= SCAN_XOK; } /*-cc-*/ if (base == 0) { base = 8; flags |= SCAN_XOK; } if (flags & SCAN_NOZERO) { flags &= ~(SCAN_SIGNOK | SCAN_NODIGITS | SCAN_NOZERO); } else { flags &= ~(SCAN_SIGNOK | SCAN_XOK | SCAN_NODIGITS); } goto addToInt; case '1': case '2': case '3': case '4': case '5': case '6': case '7': if (base == 0) { base = 10; } flags &= ~(SCAN_SIGNOK | SCAN_XOK | SCAN_NODIGITS); goto addToInt; case '8': case '9': if (base == 0) { base = 10; } if (base <= 8) { break; } flags &= ~(SCAN_SIGNOK | SCAN_XOK | SCAN_NODIGITS); goto addToInt; case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': if (base <= 10) { break; } flags &= ~(SCAN_SIGNOK | SCAN_XOK | SCAN_NODIGITS); goto addToInt; case '+': case '-': if (flags & SCAN_SIGNOK) { flags &= ~SCAN_SIGNOK; goto addToInt; } break; case 'x': case 'X': if ((flags & SCAN_XOK) && (end == buf+1)) { base = 16; flags &= ~SCAN_XOK; goto addToInt; } break; } /* * We got an illegal character so we are done accumulating. */ break; addToInt: /* * Add the character to the temporary buffer. */ *end++ = *string++; if (*string == '\0') { break; } } /* * Check to see if we need to back up because we only got a * sign or a trailing x after a 0. */ if (flags & SCAN_NODIGITS) { if (*string == '\0') { underflow = 1; } goto done; } else if (end[-1] == 'x' || end[-1] == 'X') { end--; string--; } /* * Scan the value from the temporary buffer. If we are * returning a large unsigned value, we have to convert it back * to a string since PHP only supports signed values. */ if (!(flags & SCAN_SUPPRESS)) { *end = '\0'; value = (int) (*fn)(buf, NULL, base); if ((flags & SCAN_UNSIGNED) && (value < 0)) { sprintf(buf, "%u", value); /* INTL: ISO digit */ if (numVars && objIndex >= argCount) { break; } else if (numVars) { /* change passed value type to string */ current = args[objIndex++]; convert_to_string( *current ); ZVAL_STRING( *current, buf, 1 ); } else { add_index_string(*return_value, objIndex++, buf, 1); } } else { if (numVars && objIndex >= argCount) { break; } else if (numVars) { current = args[objIndex++]; convert_to_long( *current ); Z_LVAL(**current) = value; } else { add_index_long(*return_value, objIndex++, value); } } } break; case 'f': /* * Scan a floating point number */ buf[0] = '\0'; /* call me pedantic */ if ((width == 0) || (width > sizeof(buf) - 1)) { width = sizeof(buf) - 1; } flags |= SCAN_SIGNOK | SCAN_NODIGITS | SCAN_PTOK | SCAN_EXPOK; for (end = buf; width > 0; width--) { switch (*string) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': flags &= ~(SCAN_SIGNOK | SCAN_NODIGITS); goto addToFloat; case '+': case '-': if (flags & SCAN_SIGNOK) { flags &= ~SCAN_SIGNOK; goto addToFloat; } break; case '.': if (flags & SCAN_PTOK) { flags &= ~(SCAN_SIGNOK | SCAN_PTOK); goto addToFloat; } break; case 'e': case 'E': /* * An exponent is not allowed until there has * been at least one digit. */ if ((flags & (SCAN_NODIGITS | SCAN_EXPOK)) == SCAN_EXPOK) { flags = (flags & ~(SCAN_EXPOK|SCAN_PTOK)) | SCAN_SIGNOK | SCAN_NODIGITS; goto addToFloat; } break; } /* * We got an illegal character so we are done accumulating. */ break; addToFloat: /* * Add the character to the temporary buffer. */ *end++ = *string++; if (*string == '\0') { break; } } /* * Check to see if we need to back up because we saw a * trailing 'e' or sign. */ if (flags & SCAN_NODIGITS) { if (flags & SCAN_EXPOK) { /* * There were no digits at all so scanning has * failed and we are done. */ if (*string == '\0') { underflow = 1; } goto done; } /* * We got a bad exponent ('e' and maybe a sign). */ end--; string--; if (*end != 'e' && *end != 'E') { end--; string--; } } /* * Scan the value from the temporary buffer. */ if (!(flags & SCAN_SUPPRESS)) { double dvalue; *end = '\0'; dvalue = zend_strtod(buf, NULL); if (numVars && objIndex >= argCount) { break; } else if (numVars) { current = args[objIndex++]; convert_to_double( *current ); Z_DVAL_PP( current ) = dvalue; } else { add_index_double( *return_value, objIndex++, dvalue ); } } break; } /* switch (op) */ nconversions++; } /* while (*format != '\0') */ done: result = SCAN_SUCCESS; if (underflow && (0==nconversions)) { scan_set_error_return( numVars, return_value ); result = SCAN_ERROR_EOF; } else if (numVars) { convert_to_long( *return_value ); Z_LVAL_PP(return_value) = nconversions; } else if (nconversions < totalVars) { /* to do : not all elements converted. we need to prune the list - cc */ } return result;}/* }}} *//* the compiler choked when i tried to make this a macro */static inline void scan_set_error_return(int numVars, pval **return_value){ if (numVars) { Z_TYPE_PP(return_value) = IS_LONG; Z_LVAL_PP(return_value) = SCAN_ERROR_EOF; /* EOF marker */ } else { /* pval_destructor( *return_value ); */ /* convert_to_null calls destructor */ convert_to_null( *return_value ); } }/* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: sw=4 ts=4 fdm=marker * vim<600: sw=4 ts=4 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -