📄 _fmtinpt.c
字号:
// // Visopsys// Copyright (C) 1998-2007 J. Andrew McLaughlin// // This library is free software; you can redistribute it and/or modify it// under the terms of the GNU Lesser General Public License as published by// the Free Software Foundation; either version 2.1 of the License, or (at// your option) any later version.//// This library is distributed in the hope that it will be useful, but// WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser// General Public License for more details.//// You should have received a copy of the GNU Lesser General Public License// along with this library; if not, write to the Free Software Foundation,// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.//// _fmtinpt.c//// This function does all the work of filling data values from input// based on the format strings used by the scanf family of functions// (and others, if desired)#include <ctype.h>#include <stdlib.h>#include <string.h>#include <sys/cdefs.h>int _fmtinpt(const char *input, const char *format, va_list list){ int matchItems = 0; int inputLen = 0; int formatLen = 0; int inputCount = 0; int formatCount = 0; unsigned long long *argument = NULL; int zeroPad = 0; int leftJust = 0; int fieldWidth = 0; int isLong = 0; int count; // How long are the input and format strings? inputLen = strlen(input); if (inputLen < 0) { errno = inputLen; return (matchItems = 0); } inputLen = min(inputLen, MAXSTRINGLENGTH); formatLen = strlen(format); if (formatLen < 0) { errno = formatLen; return (matchItems = 0); } formatLen = min(formatLen, MAXSTRINGLENGTH); // The argument list must already have been initialized using va_start // Loop through all of the characters in the format string for (formatCount = 0; formatCount < formatLen; ) { // If we encounter any whitespace in the format string, ignore it and // ignore any whitespace in the input if ((formatCount < formatLen) && isspace(format[formatCount])) { // Skip format string whitespace while ((formatCount < formatLen) && isspace(format[formatCount])) formatCount += 1; // Skip input whitespace while ((inputCount < inputLen) && isspace(input[inputCount])) inputCount += 1; continue; } // If "%%" appears in the format, we expect to match one '%' in the // input if ((format[formatCount] == '%') && (format[formatCount + 1] == '%')) { if (input[inputCount] != '%') { errno = ERR_BADDATA; return (matchItems); } formatCount += 2; inputCount += 1; continue; } // For other non-conversion specifiers, we simply verify that they match // and then skip them if (format[formatCount] != '%') { if (format[formatCount] != input[inputCount]) { errno = ERR_BADDATA; return (matchItems); } formatCount += 1; inputCount += 1; continue; } // Move to the next character formatCount += 1; // We have some format characters. Get the corresponding argument. // Look for a zero digit, which indicates that any field width argument // is to be zero-padded if (format[formatCount] == '0') { zeroPad = 1; formatCount += 1; } else zeroPad = 0; // Look for left-justification (applicable if there's a field-width // specifier to follow if (format[formatCount] == '-') { leftJust = 1; formatCount += 1; } else leftJust = 0; // Look for field length indicator if ((format[formatCount] >= '1') && (format[formatCount] <= '9')) { fieldWidth = atoi(format + formatCount); while ((format[formatCount] >= '0') && (format[formatCount] <= '9')) formatCount++; } else fieldWidth = 0; // If there's a 'll' qualifier for long values, make note of it if (format[formatCount] == 'l') { formatCount += 1; if (format[formatCount] == 'l') { isLong = 1; formatCount += 1; } } else isLong = 0; // We have some format characters. Get the corresponding argument. argument = (unsigned long long *) va_arg(list, unsigned); // What is it? switch(format[formatCount]) { case 'd': case 'i': // This is an integer. Read the characters for the integer // from the input string if (isLong) { *argument = atoll(input + inputCount); inputCount += _ldigits(*argument, 10, 1); } else { *((int *) argument) = atoi(input + inputCount); inputCount += _digits(*argument, 10, 1); } break; case 'u': // This is an unsigned integer. Put the characters for // the integer into the destination string if (isLong) { *argument = atoull(input + inputCount); inputCount += _ldigits(*argument, 10, 0); } else { *((unsigned *) argument) = atou(input + inputCount); inputCount += _digits(*argument, 10, 0); } break; case 'c': // A character. *((char *) argument) = input[inputCount++]; break; case 's': // This is a string. Copy until we meet a whitespace character. for (count = 0; ((inputCount < inputLen) && !isspace(input[inputCount])); count ++) ((char *) argument)[count] = input[inputCount++]; ((char *) argument)[count] = '\0'; break; case 'p': case 'x': case 'X': if (format[formatCount] == 'p') { // Bit of special stuff for pointer args if (!strncmp((input + inputCount), "0x", 2)) inputCount += 2; } if (isLong) { *argument = xtoll(input + inputCount); inputCount += _ldigits(*argument, 16, 1); } else { *((int *) argument) = xtoi(input + inputCount); inputCount += _digits(*argument, 16, 1); } break; default: // Umm, we don't know what this is. Fail. errno = ERR_INVALID; return (matchItems); break; } matchItems += 1; formatCount += 1; } // Return the number of items we matched return (matchItems);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -