sl@0: /* SSCANF.C sl@0: * sl@0: * Portions Copyright (c) 1990-2006 Nokia Corporation and/or its subsidiary(-ies). sl@0: * All rights reserved. sl@0: */ sl@0: sl@0: /* sl@0: * Copyright (c) 1990 The Regents of the University of California. sl@0: * All rights reserved. sl@0: * sl@0: * Redistribution and use in source and binary forms are permitted sl@0: * provided that the above copyright notice and this paragraph are sl@0: * duplicated in all such forms and that any documentation, sl@0: * advertising materials, and other materials related to such sl@0: * distribution and use acknowledge that the software was developed sl@0: * by the University of California, Berkeley. The name of the sl@0: * University may not be used to endorse or promote products derived sl@0: * from this software without specific prior written permission. sl@0: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR sl@0: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED sl@0: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. sl@0: */ sl@0: sl@0: /* sl@0: sl@0: FUNCTION sl@0: <>, <>, <>---scan and format input sl@0: sl@0: INDEX sl@0: scanf sl@0: INDEX sl@0: fscanf sl@0: INDEX sl@0: sscanf sl@0: sl@0: ANSI_SYNOPSIS sl@0: #include sl@0: sl@0: int scanf(const char *<[format]> [, <[arg]>, ...]); sl@0: int fscanf(FILE *<[fd]>, const char *<[format]> [, <[arg]>, ...]); sl@0: int sscanf(const char *<[str]>, const char *<[format]> sl@0: [, <[arg]>, ...]); sl@0: sl@0: sl@0: TRAD_SYNOPSIS sl@0: #include sl@0: sl@0: int scanf(<[format]> [, <[arg]>, ...]) sl@0: char *<[format]>; sl@0: sl@0: int fscanf(<[fd]>, <[format]> [, <[arg]>, ...]); sl@0: FILE *<[fd]>; sl@0: char *<[format]>; sl@0: sl@0: int sscanf(<[str]>, <[format]> [, <[arg]>, ...]); sl@0: char *<[str]>; sl@0: char *<[format]>; sl@0: sl@0: sl@0: DESCRIPTION sl@0: <> scans a series of input fields from standard input, sl@0: one character at a time. Each field is interpreted according to sl@0: a format specifier passed to <> in the format string at sl@0: <<*<[format]>>>. <> stores the interpreted input from sl@0: each field at the address passed to it as the corresponding argument sl@0: following <[format]>. You must supply the same number of sl@0: format specifiers and address arguments as there are input fields. sl@0: sl@0: There must be sufficient address arguments for the given format sl@0: specifiers; if not the results are unpredictable and likely sl@0: disasterous. Excess address arguments are merely ignored. sl@0: sl@0: <> often produces unexpected results if the input diverges from sl@0: an expected pattern. Since the combination of <> or <> sl@0: followed by <> is safe and easy, that is the preferred way sl@0: to be certain that a program is synchronized with input at the end sl@0: of a line. sl@0: sl@0: <> and <> are identical to <>, other than the sl@0: source of input: <> reads from a file, and <> sl@0: from a string. sl@0: sl@0: The string at <<*<[format]>>> is a character sequence composed sl@0: of zero or more directives. Directives are composed of sl@0: one or more whitespace characters, non-whitespace characters, sl@0: and format specifications. sl@0: sl@0: Whitespace characters are blank (<< >>), tab (<<\t>>), or sl@0: newline (<<\n>>). sl@0: When <> encounters a whitespace character in the format string sl@0: it will read (but not store) all consecutive whitespace characters sl@0: up to the next non-whitespace character in the input. sl@0: sl@0: Non-whitespace characters are all other ASCII characters except the sl@0: percent sign (<<%>>). When <> encounters a non-whitespace sl@0: character in the format string it will read, but not store sl@0: a matching non-whitespace character. sl@0: sl@0: Format specifications tell <> to read and convert characters sl@0: from the input field into specific types of values, and store then sl@0: in the locations specified by the address arguments. sl@0: sl@0: Trailing whitespace is left unread unless explicitly sl@0: matched in the format string. sl@0: sl@0: The format specifiers must begin with a percent sign (<<%>>) sl@0: and have the following form: sl@0: sl@0: . %[*][<[width]>][<[size]>]<[type]> sl@0: sl@0: Each format specification begins with the percent character (<<%>>). sl@0: The other fields are: sl@0: o+ sl@0: o * sl@0: an optional marker; if present, it suppresses interpretation and sl@0: assignment of this input field. sl@0: sl@0: o <[width]> sl@0: an optional maximum field width: a decimal integer, sl@0: which controls the maximum number of characters that sl@0: will be read before converting the current input field. If the sl@0: input field has fewer than <[width]> characters, <> sl@0: reads all the characters in the field, and then sl@0: proceeds with the next field and its format specification. sl@0: sl@0: If a whitespace or a non-convertable character occurs sl@0: before <[width]> character are read, the characters up sl@0: to that character are read, converted, and stored. sl@0: Then <> proceeds to the next format specification. sl@0: sl@0: o size sl@0: <>, <>, and <> are optional size characters which sl@0: override the default way that <> interprets the sl@0: data type of the corresponding argument. sl@0: sl@0: sl@0: .Modifier Type(s) sl@0: . h d, i, o, u, x convert input to short, sl@0: . store in short object sl@0: . sl@0: . h D, I, O, U, X no effect sl@0: . e, f, c, s, n, p sl@0: . sl@0: . l d, i, o, u, x convert input to long, sl@0: . store in long object sl@0: . sl@0: . l e, f, g convert input to double sl@0: . store in a double object sl@0: . sl@0: . l D, I, O, U, X no effect sl@0: . c, s, n, p sl@0: . sl@0: . L d, i, o, u, x convert to long double, sl@0: . store in long double sl@0: . sl@0: . L all others no effect sl@0: sl@0: sl@0: o <[type]> sl@0: sl@0: A character to specify what kind of conversion sl@0: <> performs. Here is a table of the conversion sl@0: characters: sl@0: sl@0: o+ sl@0: o % sl@0: No conversion is done; the percent character (<<%>>) is stored. sl@0: sl@0: o c sl@0: Scans one character. Corresponding <[arg]>: <<(char *arg)>>. sl@0: sl@0: o s sl@0: Reads a character string into the array supplied. sl@0: Corresponding <[arg]>: <<(char arg[])>>. sl@0: sl@0: o [<[pattern]>] sl@0: Reads a non-empty character string into memory sl@0: starting at <[arg]>. This area must be large sl@0: enough to accept the sequence and a sl@0: terminating null character which will be added sl@0: automatically. (<[pattern]> is discussed in the paragraph following sl@0: this table). Corresponding <[arg]>: <<(char *arg)>>. sl@0: sl@0: o d sl@0: Reads a decimal integer into the corresponding <[arg]>: <<(int *arg)>>. sl@0: sl@0: o D sl@0: Reads a decimal integer into the corresponding sl@0: <[arg]>: <<(long *arg)>>. sl@0: sl@0: o o sl@0: Reads an octal integer into the corresponding <[arg]>: <<(int *arg)>>. sl@0: sl@0: o O sl@0: Reads an octal integer into the corresponding <[arg]>: <<(long *arg)>>. sl@0: sl@0: o u sl@0: Reads an unsigned decimal integer into the corresponding sl@0: <[arg]>: <<(unsigned int *arg)>>. sl@0: sl@0: sl@0: o U sl@0: Reads an unsigned decimal integer into the corresponding <[arg]>: sl@0: <<(unsigned long *arg)>>. sl@0: sl@0: o x,X sl@0: Read a hexadecimal integer into the corresponding <[arg]>: sl@0: <<(int *arg)>>. sl@0: sl@0: o e, f, g sl@0: Read a floating point number into the corresponding <[arg]>: sl@0: <<(float *arg)>>. sl@0: sl@0: o E, F, G sl@0: Read a floating point number into the corresponding <[arg]>: sl@0: <<(double *arg)>>. sl@0: sl@0: o i sl@0: Reads a decimal, octal or hexadecimal integer into the sl@0: corresponding <[arg]>: <<(int *arg)>>. sl@0: sl@0: o I sl@0: Reads a decimal, octal or hexadecimal integer into the sl@0: corresponding <[arg]>: <<(long *arg)>>. sl@0: sl@0: o n sl@0: Stores the number of characters read in the corresponding sl@0: <[arg]>: <<(int *arg)>>. sl@0: sl@0: o p sl@0: Stores a scanned pointer. ANSI C leaves the details sl@0: to each implementation; this implementation treats sl@0: <<%p>> exactly the same as <<%U>>. Corresponding sl@0: <[arg]>: <<(void **arg)>>. sl@0: o- sl@0: sl@0: A <[pattern]> of characters surrounded by square brackets can be used sl@0: instead of the <> type character. <[pattern]> is a set of sl@0: characters which define a search set of possible characters making up sl@0: the <> input field. If the first character in the brackets is a sl@0: caret (<<^>>), the search set is inverted to include all ASCII characters sl@0: except those between the brackets. There is also a range facility sl@0: which you can use as a shortcut. <<%[0-9] >> matches all decimal digits. sl@0: The hyphen must not be the first or last character in the set. sl@0: The character prior to the hyphen must be lexically less than the sl@0: character after it. sl@0: sl@0: Here are some <[pattern]> examples: sl@0: o+ sl@0: o %[abcd] sl@0: matches strings containing only <>, <>, <>, and <>. sl@0: sl@0: o %[^abcd] sl@0: matches strings containing any characters except <>, <>, sl@0: <>, or <> sl@0: sl@0: o %[A-DW-Z] sl@0: matches strings containing <>, <>, <>, <>, <>, sl@0: <>, <>, <> sl@0: sl@0: o %[z-a] sl@0: matches the characters <>, <<->>, and <> sl@0: o- sl@0: sl@0: Floating point numbers (for field types <>, <>, <>, <>, sl@0: <>, <>) must correspond to the following general form: sl@0: sl@0: . [+/-] ddddd[.]ddd [E|e[+|-]ddd] sl@0: sl@0: where objects inclosed in square brackets are optional, and <> sl@0: represents decimal, octal, or hexadecimal digits. sl@0: o- sl@0: sl@0: RETURNS sl@0: <> returns the number of input fields successfully sl@0: scanned, converted and stored; the return value does sl@0: not include scanned fields which were not stored. sl@0: sl@0: If <> attempts to read at end-of-file, the return sl@0: value is <>. sl@0: sl@0: If no fields were stored, the return value is <<0>>. sl@0: sl@0: <> might stop scanning a particular field before sl@0: reaching the normal field end character, or may sl@0: terminate entirely. sl@0: sl@0: <> stops scanning and storing the current field sl@0: and moves to the next input field (if any) sl@0: in any of the following situations: sl@0: sl@0: O+ sl@0: o The assignment suppressing character (<<*>>) appears sl@0: after the <<%>> in the format specification; the current sl@0: input field is scanned but not stored. sl@0: sl@0: o <[width]> characters have been read (<[width]> is a sl@0: width specification, a positive decimal integer). sl@0: sl@0: o The next character read cannot be converted sl@0: under the the current format (for example, sl@0: if a <> is read when the format is decimal). sl@0: sl@0: o The next character in the input field does not appear sl@0: in the search set (or does appear in the inverted search set). sl@0: O- sl@0: sl@0: When <> stops scanning the current input field for one of sl@0: these reasons, the next character is considered unread and sl@0: used as the first character of the following input field, or the sl@0: first character in a subsequent read operation on the input. sl@0: sl@0: <> will terminate under the following circumstances: sl@0: sl@0: O+ sl@0: o The next character in the input field conflicts sl@0: with a corresponding non-whitespace character in the sl@0: format string. sl@0: sl@0: o The next character in the input field is <>. sl@0: sl@0: o The format string has been exhausted. sl@0: O- sl@0: sl@0: When the format string contains a character sequence that is sl@0: not part of a format specification, the same character sl@0: sequence must appear in the input; <> will sl@0: scan but not store the matched characters. If a sl@0: conflict occurs, the first conflicting character remains in the input sl@0: as if it had never been read. sl@0: sl@0: PORTABILITY sl@0: <> is ANSI C. sl@0: sl@0: Supporting OS subroutines required: <>, <>, <>, sl@0: <>, <>, <>, <>. sl@0: */ sl@0: sl@0: #include <_ansi.h> sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include "LOCAL.H" sl@0: sl@0: static sl@0: int sl@0: eofread (void* cookie,char *buf,int len) sl@0: { sl@0: cookie=cookie; sl@0: buf=buf; sl@0: len=len; sl@0: return 0; sl@0: } sl@0: sl@0: /** sl@0: Read formatted data from string. sl@0: Reads data from the buffer specified and stores it sl@0: into the locations given by argument(s). sl@0: Locations pointed by each argument are filled with their corresponding type sl@0: of value requested in the format string. sl@0: sl@0: @param str Buffer containing the string to be parsed for data. sl@0: @param fmt String that can contain one or more of these items: sl@0: Whitespace characters: the function will read and ignore any whitespace sl@0: characters (this includes blank, newline and tab characters) encountered sl@0: before the next non-whitespace character. This includes any quantity of sl@0: whitespace characters (including none). On-whitespace characters (any sl@0: character not including blank, newline, tab, or any format specifier sl@0: begining with % character): this cause that the function read and discard sl@0: any character that match the given non-whitespace character. If this sl@0: character is not found the function ends returning error. sl@0: Format specifiers: A sequence of characters begining with '%' indicates sl@0: that next data has to be readed and stored at the location pointed by its sl@0: corresponding argument with a given format that is specified following this sl@0: prototype: %[*][width][modifiers]type sl@0: sl@0: @return On Success, The number of items succesfully read. This count doesn't include any sl@0: ignored fields. sl@0: On Failure, returns EOF, if an error has occurred before the first assignation sl@0: could be done and errno may be set. sl@0: */ sl@0: EXPORT_C int sscanf(const char *str, const char *fmt, ...) sl@0: { sl@0: int ret; sl@0: va_list ap; sl@0: FILE f; sl@0: sl@0: f._data = _REENT2; sl@0: if (!f._data) sl@0: return EOF; // Memory for library globals is not allocated (errno not set). sl@0: sl@0: f._flags = __SRD; sl@0: f._bf._base = f._p = (unsigned char *) str; sl@0: f._bf._size = f._r = strlen (str); sl@0: f._read = eofread; sl@0: f._ub._base = NULL; sl@0: f._lb._base = NULL; sl@0: sl@0: va_start (ap, fmt); sl@0: ret = __svfscanf (&f, fmt, ap); sl@0: va_end (ap); sl@0: return ret; sl@0: }