scanf() — Read Data

Format

#include <stdio.h>
int scanf(const char *format-string, argument-list);

Language Level: ANSI

Threadsafe: Yes.

Locale Sensitive: The behavior of this function might be affected by the LC_CTYPE and LC_NUMERIC categories of the current locale. The behavior might also be affected by the LC_UNI_CTYPE category of the current locale if LOCALETYPE(*LOCALEUCS2) or LOCALETYPE(*LOCALEUTF) is specified on the compilation command. For more information, see Understanding CCSIDs and Locales.

Description

The scanf() function reads data from the standard input stream stdin into the locations given by each entry in argument-list. Each argument must be a pointer to a variable with a type that corresponds to a type specifier in format-string. The format-string controls the interpretation of the input fields, and is a multibyte character string that begins and ends in its initial shift state.

The format-string can contain one or more of the following:

The scanf() function reads format-string from left to right. Characters outside of format specifications are expected to match the sequence of characters in stdin; the matched characters in stdin are scanned but not stored. If a character in stdin conflicts with format-string, scanf() ends. The conflicting character is left in stdin as if it had not been read.

When the first format specification is found, the value of the first input field is converted according to the format specification and stored in the location specified by the first entry in argument-list. The second format specification converts the second input field and stores it in the second entry in argument-list, and so on through the end of format-string.

An input field is defined as all characters up to the first white-space character (space, tab, or new line), up to the first character that cannot be converted according to the format specification, or until the field width is reached, whichever comes first. If there are too many arguments for the format specifications, the extra arguments are ignored. The results are undefined if there are not enough arguments for the format specifications.

A format specification has the following form:

Read syntax diagramSkip visual syntax diagram>>-%--+---+--+-------+--+----+--type---------------------------><
      '-*-'  '-width-'  +-h--+
                        +-L--+
                        +-l--+
                        +-ll-+
                        +-H--+
                        +-D--+
                        '-DD-'
 

Each field of the format specification is a single character or a number signifying a particular format option. The type character, which appears after the last optional format field, determines whether the input field is interpreted as a character, a string, or a number. The simplest format specification contains only the percent sign and a type character (for example, %s).

Each field of the format specification is discussed in detail below. If a percent sign (%) is followed by a character that has no meaning as a format control character, that character and following characters up to the next percent sign are treated as an ordinary sequence of characters; that is, a sequence of characters that must match the input. For example, to specify a percent-sign character, use %%.

The following restrictions apply to pointer printing and scanning:

See the IBM Rational Development Studio for i: ILE C/C++ Programmer's Guide for more information about using i5/OS pointers.

An asterisk (*) following the percent sign suppresses assignment of the next input field, which is interpreted as a field of the specified type. The field is scanned but not stored.

The width is a positive decimal integer controlling the maximum number of characters to be read from stdin. No more than width characters are converted and stored at the corresponding argument. Fewer than width characters are read if a white-space character (space, tab, or new line), or a character that cannot be converted according to the given format occurs before width is reached.

The optional size modifiers h, l, ll, L, H, D, and DD indicate the size of the receiving object. The conversion characters d, i, and n must be preceded by h if the corresponding argument is a pointer to a short int rather than a pointer to an int, by l if it is a pointer to a long int, or by ll if it is a pointer to a long long int. Similarly, the conversion characters o, u, x, and X must be preceded by h if the corresponding argument is a pointer to an unsigned short int rather than a pointer to an unsigned int, by l if it is a pointer to an unsigned long int, or by ll if it is a pointer to an unsigned long long int. The conversion characters e, E, f, F, g, and G must be preceded by l if the corresponding argument is a pointer to a double rather than a pointer to a float, by L if it is a pointer to a long double, by H if it is a pointer to a _Decimal32, by D if it is a pointer to a _Decimal64, or by DD if it is a pointer to a _Decimal128. Finally, the conversion characters c, s, and [ must be preceded by l if the corresponding argument is a pointer to a wchar_t rather than a pointer to a single-byte character type. If an h, l, L, ll, H, D, or DD appears with any other conversion character, the behavior is undefined.

The type characters and their meanings are in the following table:

Character Type of Input Expected Type of Argument
d Signed decimal integer Pointer to int.
o Unsigned octal integer Pointer to unsigned int.
x, X Unsigned hexadecimal integer Pointer to unsigned int.
i Decimal, hexadecimal, or octal integer Pointer to int.
u Unsigned decimal integer Pointer to unsigned int.
e, E, f, F, g, G Floating-point value consisting of an optional sign (+ or -); a series of one or more decimal digits possibly containing a decimal point; and an optional exponent (e or E) followed by a possibly signed integer value. Pointer to floating point.
D(n,p) Packed decimal value consisting of an optional sign (+ or -); then a non-empty sequence of digits, optionally a series of one or more decimal digits possibly containing a decimal point, but not a decimal suffix. The subject sequence is defined as the longest initial subsequence of the input string, starting with the first non-whitespace character, in the expected form. It contains no characters if the input string is empty or consists entirely of white space, or if the first non-whitespace character is anything other than a sign, a digit, or a decimal point character. Pointer to decimal(n,p). Since the internal representation of the binary coded decimal object is the same as the internal representation of the packed decimal data type, you can use the type character D(n,p).
c Character; white-space characters that are ordinarily skipped are read when c is specified Pointer to char large enough for input field.
s String Pointer to character array large enough for input field plus a ending null character (\0), which is automatically appended.
n No input read from stream or buffer Pointer to int, into which is stored the number of characters successfully read from the stream or buffer up to that point in the call to scanf().
p Pointer to void converted to series of characters Pointer to void.
lc Multibyte character constant Pointer to wchar_t.
ls Multibyte string constant Pointer to wchar_t string.

To read strings not delimited by space characters, substitute a set of characters in brackets ([ ]) for the s (string) type character. The corresponding input field is read up to the first character that does not appear in the bracketed character set. If the first character in the set is a caret (^), the effect is reversed: the input field is read up to the first character that does appear in the rest of the character set.

To store a string without storing an ending null character (\0), use the specification %ac, where a is a decimal integer. In this instance, the c type character means that the argument is a pointer to a character array. The next a characters are read from the input stream into the specified location, and no null character is added.

The input for a %x format specifier is interpreted as a hexadecimal number.

The scanf() function scans each input field character by character. It might stop reading a particular input field either before it reaches a space character, when the specified width is reached, or when the next character cannot be converted as specified. When a conflict occurs between the specification and the input character, the next input field begins at the first unread character. The conflicting character, if there was one, is considered unread and is the first character of the next input field or the first character in subsequent read operations on stdin.

For %lc and %ls, specifies the data that is read is a multibyte string and is converted to wide characters as if by calls to mbtowc.

For the %e, %E, %f, %F, %g, and %G format specifiers, a character sequence of INFINITY or NAN (ignoring case) is allowed and yields a value of INFINITY or Quiet Not-A-Number (NaN), respectively.

Alternative format specification has the following form:

Read syntax diagramSkip visual syntax diagram>>-%--arg-number$--+---+--+-------+--+----+--type--------------><
                   '-*-'  '-width-'  +-h--+
                                     +-L--+
                                     +-l--+
                                     +-ll-+
                                     +-H--+
                                     +-D--+
                                     '-DD-'
 

As an alternative, specific entries in the argument-list may be assigned by using the format specification outlined in the diagram above. This format specification and the previous format specification may not be mixed in the same call to scanf(). Otherwise, unpredictable results may occur.

The arg-number is a positive integer constant where 1 refers to the first entry in the argument-list. Arg-number may not be greater than the number of entries in the argument-list, or else the results are undefined. Arg-number also may not be greater than NL_ARGMAX.

Return Value

The scanf() function returns the number of fields that were successfully converted and assigned. The return value does not include fields that were read but not assigned.

The return value is EOF for an attempt to read at end-of-file if no conversion was performed. A return value of 0 means that no fields were assigned.

Error Conditions

If the type of the argument that is to be assigned into is different than the format specification, unpredictable results can occur. For example, reading a floating-point value, but assigning it into a variable of type int, is incorrect and would have unpredictable results.

If there are more arguments than format specifications, the extra arguments are ignored. The results are undefined if there are not enough arguments for the format specifications.

If the format string contains an invalid format specification, and positional format specifications are being used, errno will be set to EILSEQ.

If positional format specifications are used and there are not enough arguments, errno will be set to EINVAL.

If a conversion error occurs, errno may be set to ECONVERT.

Examples using scanf()

This example scans various types of data.

#include <stdio.h>
 
int main(void)
{
   int i;
   float fp;
   char c, s[81];
 
   printf("Enter an integer, a real number, a character "
          "and a string : \n");
   if (scanf("%d %f %c %s", &i, &fp, &c, s) != 4)
      printf("Not all fields were assigned\n");
   else
   {
      printf("integer = %d\n", i);
      printf("real number = %f\n", fp);
      printf("character = %c\n", c);
      printf("string = %s\n",s);
   }
}
 
/*****************  If input is: 12 2.5 a yes,  *******************
**************  then output should be similar to:  ****************
 
Enter an integer, a real number, a character and a string :
integer = 12
real number = 2.500000
character = a
string = yes
*/

This example converts a hexadecimal integer to a decimal integer. The while loop ends if the input value is not a hexadecimal integer.

#include <stdio.h>
 
int main(void)
{
   int number;
 
   printf("Enter a hexadecimal number or anything else to quit:\n");
   while (scanf("%x",&number))
      {
      printf("Hexadecimal Number = %x\n",number);
      printf("Decimal Number     = %d\n",number);
      }
}
 
/***************  If input is: 0x231 0xf5e 0x1 q,  **************      **
****************  then output should be similar to:  **************
 
Enter a hexadecimal number or anything else to quit:
Hexadecimal Number = 231
Decimal Number     = 561
Hexadecimal Number = f5e
Decimal Number     = 3934
Hexadecimal Number = 1
Decimal Number     = 1
*/

This example reads from stdin and assigns data by using the alternative positional format string.

#include <stdio.h>
int main(int argc, char *argv[])
{
int i;
char s[20];
float f;

scanf("%2$s %3$f %1$d",&i, s, &f);

printf("The data read was %i\n%s\n%f\n,i,s,f);

return 0;
 }

 /* If the input is : test 0.2 100
    then the output will be similar to: */
   The data read was
 100
 test
 0.20000

 -------------------------------------------------------------------- 

This example reads in a multibyte character string into a wide Unicode string. The example can be compiled with either LOCALETYPE(*LOCALEUCS2) or LOCALETYPE(*LOCALEUTF).

 #include <locale.h>
 #include <stdio.h>
 #include <wchar.h>

 void main(void)
{
wchar_t uString[20];

setlocale(LC_UNI_ALL, "");
scanf("Enter a string %ls",uString);

printf("String read was %ls\n",uString);
}

/* if the input is : ABC
   then the output will be similiar to:

   String read was ABC

 */                                                              

Related Information



[ Top of Page | Previous Page | Next Page | Contents | Index ]