0,0 → 1,469 |
/* |
* Copyright (c) 1990 The Regents of the University of California. |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms are permitted |
* provided that the above copyright notice and this paragraph are |
* duplicated in all such forms and that any documentation, |
* advertising materials, and other materials related to such |
* distribution and use acknowledge that the software was developed |
* by the University of California, Berkeley. The name of the |
* University may not be used to endorse or promote products derived |
* from this software without specific prior written permission. |
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED |
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
*/ |
|
/* |
FUNCTION |
<<sscanf>>, <<fscanf>>, <<scanf>>---scan and format input |
|
INDEX |
scanf |
INDEX |
_scanf_r |
INDEX |
fscanf |
INDEX |
_fscanf_r |
INDEX |
sscanf |
INDEX |
_sscanf_r |
|
ANSI_SYNOPSIS |
#include <stdio.h> |
|
int scanf(const char *<[format]>, ...); |
int fscanf(FILE *<[fd]>, const char *<[format]>, ...); |
int sscanf(const char *<[str]>, const char *<[format]>, ...); |
|
int _scanf_r(struct _reent *<[ptr]>, const char *<[format]>, ...); |
int _fscanf_r(struct _reent *<[ptr]>, FILE *<[fd]>, |
const char *<[format]>, ...); |
int _sscanf_r(struct _reent *<[ptr]>, const char *<[str]>, |
const char *<[format]>, ...); |
|
|
TRAD_SYNOPSIS |
#include <stdio.h> |
|
int scanf(<[format]> [, <[arg]>, ...]) |
char *<[format]>; |
|
int fscanf(<[fd]>, <[format]> [, <[arg]>, ...]); |
FILE *<[fd]>; |
char *<[format]>; |
|
int sscanf(<[str]>, <[format]> [, <[arg]>, ...]); |
char *<[str]>; |
char *<[format]>; |
|
int _scanf_r(<[ptr]>, <[format]> [, <[arg]>, ...]) |
struct _reent *<[ptr]>; |
char *<[format]>; |
|
int _fscanf_r(<[ptr]>, <[fd]>, <[format]> [, <[arg]>, ...]); |
struct _reent *<[ptr]>; |
FILE *<[fd]>; |
char *<[format]>; |
|
int _sscanf_r(<[ptr]>, <[str]>, <[format]> [, <[arg]>, ...]); |
struct _reent *<[ptr]>; |
char *<[str]>; |
char *<[format]>; |
|
|
DESCRIPTION |
<<scanf>> scans a series of input fields from standard input, |
one character at a time. Each field is interpreted according to |
a format specifier passed to <<scanf>> in the format string at |
<<*<[format]>>>. <<scanf>> stores the interpreted input from |
each field at the address passed to it as the corresponding argument |
following <[format]>. You must supply the same number of |
format specifiers and address arguments as there are input fields. |
|
There must be sufficient address arguments for the given format |
specifiers; if not the results are unpredictable and likely |
disasterous. Excess address arguments are merely ignored. |
|
<<scanf>> often produces unexpected results if the input diverges from |
an expected pattern. Since the combination of <<gets>> or <<fgets>> |
followed by <<sscanf>> is safe and easy, that is the preferred way |
to be certain that a program is synchronized with input at the end |
of a line. |
|
<<fscanf>> and <<sscanf>> are identical to <<scanf>>, other than the |
source of input: <<fscanf>> reads from a file, and <<sscanf>> |
from a string. |
|
The routines <<_scanf_r>>, <<_fscanf_r>>, and <<_sscanf_r>> are reentrant |
versions of <<scanf>>, <<fscanf>>, and <<sscanf>> that take an additional |
first argument pointing to a reentrancy structure. |
|
The string at <<*<[format]>>> is a character sequence composed |
of zero or more directives. Directives are composed of |
one or more whitespace characters, non-whitespace characters, |
and format specifications. |
|
Whitespace characters are blank (<< >>), tab (<<\t>>), or |
newline (<<\n>>). |
When <<scanf>> encounters a whitespace character in the format string |
it will read (but not store) all consecutive whitespace characters |
up to the next non-whitespace character in the input. |
|
Non-whitespace characters are all other ASCII characters except the |
percent sign (<<%>>). When <<scanf>> encounters a non-whitespace |
character in the format string it will read, but not store |
a matching non-whitespace character. |
|
Format specifications tell <<scanf>> to read and convert characters |
from the input field into specific types of values, and store then |
in the locations specified by the address arguments. |
|
Trailing whitespace is left unread unless explicitly |
matched in the format string. |
|
The format specifiers must begin with a percent sign (<<%>>) |
and have the following form: |
|
. %[*][<[width]>][<[size]>]<[type]> |
|
Each format specification begins with the percent character (<<%>>). |
The other fields are: |
o+ |
o * |
an optional marker; if present, it suppresses interpretation and |
assignment of this input field. |
|
o <[width]> |
an optional maximum field width: a decimal integer, |
which controls the maximum number of characters that |
will be read before converting the current input field. If the |
input field has fewer than <[width]> characters, <<scanf>> |
reads all the characters in the field, and then |
proceeds with the next field and its format specification. |
|
If a whitespace or a non-convertable character occurs |
before <[width]> character are read, the characters up |
to that character are read, converted, and stored. |
Then <<scanf>> proceeds to the next format specification. |
|
o size |
<<h>>, <<j>>, <<l>>, <<L>>, <<t>>, and <<z>> are optional size |
characters which override the default way that <<scanf>> |
interprets the data type of the corresponding argument. |
|
|
.Modifier Type(s) |
. hh d, i, o, u, x, n convert input to char, |
. store in char object |
. |
. h d, i, o, u, x, n convert input to short, |
. store in short object |
. |
. h D, I, O, U, X no effect |
. e, f, c, s, p |
. |
. j d, i, o, u, x, n convert input to intmax_t, |
. store in intmax_t object |
. |
. j all others no effect |
. |
. l d, i, o, u, x, n convert input to long, |
. store in long object |
. |
. l e, f, g convert input to double |
. store in a double object |
. |
. l D, I, O, U, X no effect |
. c, s, p |
. |
. ll d, i, o, u, x, n convert to long long, |
. store in long long |
. |
. L d, i, o, u, x, n convert to long long, |
. store in long long |
. |
. L e, f, g, E, G convert to long double, |
. store in long double |
. |
. L all others no effect |
. |
. t d, i, o, u, x, n convert input to ptrdiff_t, |
. store in ptrdiff_t object |
. |
. t all others no effect |
. |
. z d, i, o, u, x, n convert input to size_t, |
. store in size_t object |
. |
. z all others no effect |
. |
|
|
o <[type]> |
|
A character to specify what kind of conversion |
<<scanf>> performs. Here is a table of the conversion |
characters: |
|
o+ |
o % |
No conversion is done; the percent character (<<%>>) is stored. |
|
o c |
Scans one character. Corresponding <[arg]>: <<(char *arg)>>. |
|
o s |
Reads a character string into the array supplied. |
Corresponding <[arg]>: <<(char arg[])>>. |
|
o [<[pattern]>] |
Reads a non-empty character string into memory |
starting at <[arg]>. This area must be large |
enough to accept the sequence and a |
terminating null character which will be added |
automatically. (<[pattern]> is discussed in the paragraph following |
this table). Corresponding <[arg]>: <<(char *arg)>>. |
|
o d |
Reads a decimal integer into the corresponding <[arg]>: <<(int *arg)>>. |
|
o D |
Reads a decimal integer into the corresponding |
<[arg]>: <<(long *arg)>>. |
|
o o |
Reads an octal integer into the corresponding <[arg]>: <<(int *arg)>>. |
|
o O |
Reads an octal integer into the corresponding <[arg]>: <<(long *arg)>>. |
|
o u |
Reads an unsigned decimal integer into the corresponding |
<[arg]>: <<(unsigned int *arg)>>. |
|
|
o U |
Reads an unsigned decimal integer into the corresponding <[arg]>: |
<<(unsigned long *arg)>>. |
|
o x,X |
Read a hexadecimal integer into the corresponding <[arg]>: |
<<(int *arg)>>. |
|
o e, f, g |
Read a floating-point number into the corresponding <[arg]>: |
<<(float *arg)>>. |
|
o E, F, G |
Read a floating-point number into the corresponding <[arg]>: |
<<(double *arg)>>. |
|
o i |
Reads a decimal, octal or hexadecimal integer into the |
corresponding <[arg]>: <<(int *arg)>>. |
|
o I |
Reads a decimal, octal or hexadecimal integer into the |
corresponding <[arg]>: <<(long *arg)>>. |
|
o n |
Stores the number of characters read in the corresponding |
<[arg]>: <<(int *arg)>>. |
|
o p |
Stores a scanned pointer. ANSI C leaves the details |
to each implementation; this implementation treats |
<<%p>> exactly the same as <<%U>>. Corresponding |
<[arg]>: <<(void **arg)>>. |
o- |
|
A <[pattern]> of characters surrounded by square brackets can be used |
instead of the <<s>> type character. <[pattern]> is a set of |
characters which define a search set of possible characters making up |
the <<scanf>> input field. If the first character in the brackets is a |
caret (<<^>>), the search set is inverted to include all ASCII characters |
except those between the brackets. There is also a range facility |
which you can use as a shortcut. <<%[0-9] >> matches all decimal digits. |
The hyphen must not be the first or last character in the set. |
The character prior to the hyphen must be lexically less than the |
character after it. |
|
Here are some <[pattern]> examples: |
o+ |
o %[abcd] |
matches strings containing only <<a>>, <<b>>, <<c>>, and <<d>>. |
|
o %[^abcd] |
matches strings containing any characters except <<a>>, <<b>>, |
<<c>>, or <<d>> |
|
o %[A-DW-Z] |
matches strings containing <<A>>, <<B>>, <<C>>, <<D>>, <<W>>, |
<<X>>, <<Y>>, <<Z>> |
|
o %[z-a] |
matches the characters <<z>>, <<->>, and <<a>> |
o- |
|
Floating point numbers (for field types <<e>>, <<f>>, <<g>>, <<E>>, |
<<F>>, <<G>>) must correspond to the following general form: |
|
. [+/-] ddddd[.]ddd [E|e[+|-]ddd] |
|
where objects inclosed in square brackets are optional, and <<ddd>> |
represents decimal, octal, or hexadecimal digits. |
o- |
|
RETURNS |
<<scanf>> returns the number of input fields successfully |
scanned, converted and stored; the return value does |
not include scanned fields which were not stored. |
|
If <<scanf>> attempts to read at end-of-file, the return |
value is <<EOF>>. |
|
If no fields were stored, the return value is <<0>>. |
|
<<scanf>> might stop scanning a particular field before |
reaching the normal field end character, or may |
terminate entirely. |
|
<<scanf>> stops scanning and storing the current field |
and moves to the next input field (if any) |
in any of the following situations: |
|
O+ |
o The assignment suppressing character (<<*>>) appears |
after the <<%>> in the format specification; the current |
input field is scanned but not stored. |
|
o <[width]> characters have been read (<[width]> is a |
width specification, a positive decimal integer). |
|
o The next character read cannot be converted |
under the the current format (for example, |
if a <<Z>> is read when the format is decimal). |
|
o The next character in the input field does not appear |
in the search set (or does appear in the inverted search set). |
O- |
|
When <<scanf>> stops scanning the current input field for one of |
these reasons, the next character is considered unread and |
used as the first character of the following input field, or the |
first character in a subsequent read operation on the input. |
|
<<scanf>> will terminate under the following circumstances: |
|
O+ |
o The next character in the input field conflicts |
with a corresponding non-whitespace character in the |
format string. |
|
o The next character in the input field is <<EOF>>. |
|
o The format string has been exhausted. |
O- |
|
When the format string contains a character sequence that is |
not part of a format specification, the same character |
sequence must appear in the input; <<scanf>> will |
scan but not store the matched characters. If a |
conflict occurs, the first conflicting character remains in the input |
as if it had never been read. |
|
PORTABILITY |
<<scanf>> is ANSI C. |
|
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>, |
<<lseek>>, <<read>>, <<sbrk>>, <<write>>. |
*/ |
|
#include <_ansi.h> |
#include <reent.h> |
#include <stdio.h> |
#include <string.h> |
#ifdef _HAVE_STDC |
#include <stdarg.h> |
#else |
#include <varargs.h> |
#endif |
#include "local.h" |
|
#ifndef _REENT_ONLY |
|
#ifdef _HAVE_STDC |
int |
_DEFUN(sscanf, (str, fmt), |
_CONST char *str _AND |
_CONST char *fmt _DOTS) |
#else |
int |
sscanf(str, fmt, va_alist) |
_CONST char *str; |
_CONST char *fmt; |
va_dcl |
#endif |
{ |
int ret; |
va_list ap; |
FILE f; |
|
f._flags = __SRD | __SSTR; |
f._bf._base = f._p = (unsigned char *) str; |
f._bf._size = f._r = strlen (str); |
f._read = __seofread; |
f._ub._base = NULL; |
f._lb._base = NULL; |
f._file = -1; /* No file. */ |
#ifdef _HAVE_STDC |
va_start (ap, fmt); |
#else |
va_start (ap); |
#endif |
ret = __ssvfscanf_r (_REENT, &f, fmt, ap); |
va_end (ap); |
return ret; |
} |
|
#endif /* !_REENT_ONLY */ |
|
#ifdef _HAVE_STDC |
int |
_DEFUN(_sscanf_r, (ptr, str, fmt), |
struct _reent *ptr _AND |
_CONST char *str _AND |
_CONST char *fmt _DOTS) |
#else |
int |
_sscanf_r(ptr, str, fmt, va_alist) |
struct _reent *ptr; |
_CONST char *str; |
_CONST char *fmt; |
va_dcl |
#endif |
{ |
int ret; |
va_list ap; |
FILE f; |
|
f._flags = __SRD | __SSTR; |
f._bf._base = f._p = (unsigned char *) str; |
f._bf._size = f._r = strlen (str); |
f._read = __seofread; |
f._ub._base = NULL; |
f._lb._base = NULL; |
f._file = -1; /* No file. */ |
#ifdef _HAVE_STDC |
va_start (ap, fmt); |
#else |
va_start (ap); |
#endif |
ret = __ssvfscanf_r (ptr, &f, fmt, ap); |
va_end (ap); |
return ret; |
} |