gtpc2m3aC/C++ Language Support User's Guide

fscanf, scanf, sscanf-Read and Format Data

These functions read and format data.

Format

#include <stdio.h>
int fscanf (FILE *:stream, const char *format, ...);
int scanf(const char *format, ...);
int sscanf(const char *buffer, const char *format, ...);

stream
The stream from which the text input will be read.

format
A specification of the format and conversions to be applied to the input text.

buffer
The string from which the input text will be read.

...
Additional pointers to objects that will contain the converted data.
ISO-C only

The fscanf function is not available in the TARGET(TPF) C library. The scanf() function in the TARGET(TPF) library is a limited and nonstandard substitute for the standard scanf() function. The TARGET(TPF) library has no support for files, stdin, or file redirection.

The TARGET(TPF) version of the scanf() function does not have the same effect as the ISO-C version. Results cannot be predicted if you use both versions in the same application.

The fscanf function reads data from the current position of the specified stream into the locations given by the entries in the argument list, if any. The argument list, if it exists, follows the format string.

The scanf function reads data from standard input stream stdin into the locations given by each entry in the argument list. The argument list, if it exists, follows the format string.

TARGET(TPF) restrictions

The format controls for the TARGET(TPF) scanf function are limited to those described in SAA Common Programming Interface C Reference - Level 2.

All TARGET(TPF) restrictions described for the gets function also apply to the scanf function, which, therefore, depends on the method of implementation at your installation.

Note:
This function relies on the gets function to operate correctly. If scanf is called and gets support does not exist, control is transferred to the system error routine.

The sscanf function reads data from buffer into the locations given by argument list. Reaching the end of the string pointed to by buffer is equivalent to the fscanf function reaching the end-of-file (EOF). If the strings pointed to by buffer and format overlap, the behavior is not defined.

The fscanf and scanf functions have the same restriction as any read operation for a read immediately following a write, or a write immediately following a read. Between a write and a subsequent read, there must be an intervening flush or reposition. Between a read and a subsequent write, there must be an intervening reposition unless an end-of-file (EOF) has been reached.

For all three functions, each entry in the argument list must be a pointer to a variable of a type that matches the corresponding conversion specification in format. If the types do not match, the results are not defined.

For all three functions, the format controls the interpretation of the argument list. The format can contain multibyte characters beginning and ending in the initial shift state.

The format string pointed to by format can contain one or more of the following:

All three functions read format from left to right. Characters outside of conversion specifications are expected to match the sequence of characters in the input stream; the matched characters in the input stream are scanned but not stored. If a character in the input stream conflicts with format-string, the function ends, ending with a matching failure. The conflicting character is left in the input stream as if it had not been read.

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

An input field is defined as:

If there are too many arguments for the conversion specifications, the extra arguments are evaluated but otherwise ignored. The results are not defined if there are not enough arguments for the conversion specifications.



Each field of the conversion specification is a single character or a number signifying a particular format option. The conversion specifier, 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 conversion specification contains only the percent sign and a conversion specifier (for example, %s).

A detailed discussion of each field of the format specification follows.

To represent the character (%) in the format string, use a double percent sign (%%). A single percent sign % must always begin a conversion specifier. See Table 8 for a list of conversion specifiers.

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

width is a positive decimal integer controlling the maximum number of characters to be read. 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.

Optional prefix l shows that you use the long version of the following conversion specifier while prefix h indicates that the short version will be used. The corresponding argument should point to a long or double object (for the l character), a long double object (for the L character), or a short object (with the h character). The l and h modifiers can be used with the d, i, o, x, and u conversion specifiers. The l modifier can also be used with the e, f, and g conversion specifiers. The L modifier can be used with the e, f, and g conversion specifiers. Note that the l modifier is also used with the c and s conversion specifiers to indicate a multibyte character or string. The l and h modifiers are ignored if specified for any other conversion specifier.

The type characters and their meanings are in Table 8.

Table 8. Conversion Specifiers in the fscanf and scanf functions

Conversion Specifier Type of Input Expected Type of Argument
d Decimal integer. Pointer to int.
o Octal integer. Pointer to unsigned int.
x
X
Hexadecimal integer. Pointer to unsigned int.
i Decimal, hexadecimal, or octal integer. Pointer to int.
u Unsigned decimal integer. Pointer to unsigned int.
e
f
g
E
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 float
D(n,p) Fixed-point value consisting of an optional sign (+ or -); a series of one or more decimal digits possibly containing a decimal point. Pointer to decimal.
c (Can be used with the l modifier as lc). Character; white-space characters that are ordinarily skipped are read when c is specified. Pointer to char large enough for input field.
C or lc The input matches the number of multibyte characters specified by the field width. Each multibyte character in the sequence is converted to a wide character as if by a call to the mbstowcs function. The conversion state described by the mbstate_t object is initialized to zero before the first multibyte character is converted. The number of wide characters matched is specified by the field width (1 if no field width is present in the directive). The corresponding argument is a pointer to the initial element of an array of wchar_t large enough to accept the resulting sequence of wide characters. No null wide character is added. C or lc uses a pointer to wchar_t string.
s (Can be used with the l modifier as ls). String, which matches a sequence of multibyte characters that begins and ends in the initial shift state. None of the multibyte characters in the sequence are also single-byte white-space characters (as specified by the isspace function). Each multibyte character in the sequence is converted to a wide character as if by a call to the mbrtowc function, with the conversion state described by the mbstate_t object initialized to zero before the first multibyte character is converted. Pointer to a character array large enough for input field, plus a terminating null character (\0) that is automatically appended.
S or ls The corresponding argument is a pointer to the initial array of wchar_t large enough to accept the sequence and the terminating null wide character, which is added automatically. S or ls uses a pointer to wchar_t string.
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.
p Pointer to void converted to series of characters. The input format is equivalent to the x or X conversion specififier. Pointer to void.
[ ] A nonempty sequence of bytes from a set of expected bytes (the scanset) that form the conversion specification. The conversion continues reading bytes until a failure to match or until an input failure.

Consider the following conditions:

[^bytes].  In this case, the scanset contains all bytes that do not appear between the circumflex and the right square bracket.

[]abc] or [^]abc.]    In both these cases the right square bracket is included in the scanset (in the first case: ]abc and in the second case, not ]abc).

[a-z]  The - is in the scanset; the characters b through y are not in the scanset.

The code point for the square brackets ([ and ]) and the caret (^) vary among the EBCDIC encoded character sets. The default C locale expects these characters to use the code points for encoded character set Latin-1 / Open Systems 1047. Conversion proceeds 1 byte at a time; there is no conversion to wide characters.

Pointer to the initial byte of an array of char, signed char, or unsigned char, large enough to accept the sequence and a terminating byte, that will be added automatically.

To read strings not delimited by space characters, substitute a set of characters in square brackets ([ ]) for the s (string) conversion specifier. 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 logical not (^), 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 conversion specifier 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 conversion specifier is interpreted as a hexadecimal number.

All three functions (fscanf, scanf, and sscanf) scan each input field character by character. The function 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 character that is not read. The conflicting character, if there is one, is considered unread and is the first character of the next input field or the first character in subsequent read operations on the input stream.

Normal Return

All three functions (fscanf, scanf, and sscanf) return the number of input items that were successfully matched and assigned. The return value does not include conversions that were performed but not assigned (for example, suppressed assignments).

Error Return

The functions return EOF if there is an input failure before any conversion or if EOF is reached before any conversion. Therefore, a return value of 0 means that no fields were assigned; there was a matching failure before any conversion. Also, if there is an input failure, the file error indicator is set, which is not the case for a matching failure.

The ferror and feof functions are used to distinguish between a read error and an EOF.

Note:
EOF is reached only when an attempt is made to read beyond the last byte of data.

Reading up to and including the last byte of data does not turn on the EOF indicator.

Programming Considerations

None.

Examples

The following 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 of the 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);
   }
}

Output

If input is: 12 2.5 a yes, then output would be:

Enter an integer, a real number, a character and a string:
integer = 12
real number = 2.500000
character = a
string = yes

The following 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);
      }
}

Output

If input is: 0x231 0xf5e 0x1 q, output would be:

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

The following example shows the use of scanf to input fixed-point decimal data types.

#include <stdio.h>
#include <decimal.h>
 
decimal(15,4) pd01;
decimal(10,2) pd02;
decimal(5,5) pd03;
 
int main(void) {
  printf("\nFirst time :-------------------------------\n");
  printf("Enter three fixed-point decimal number\n");
  printf("  (15,4) (10,2) (5,5)\n");
  if (scanf("%D(15,4) %D(10,2) %D(5,5)", &pd01, &pd02, &pd03) != 3) {
    printf("Error found in scanf\n");
  } else {
    printf("pd01 = %D(15,4)\n", pd01);
    printf("pd02 = %D(10,2)\n", pd02);
    printf("pd03 = %D(5,5)\n", pd03);
  }
  printf("\nSecond time :------------------------------\n");
  printf("Enter three fixed-point decimal number\n");
  printf("  (15,4) (10,2) (5,5)\n");
  if (scanf("%D(15,4) %D(10,2) %D(5,5)", &pd01, &pd02, &pd03) != 3) {
    printf("Error found in scanf\n");
  } else {
    printf("pd01 = %D(15,4)\n", pd01);
    printf("pd02 = %D(10,2)\n", pd02);
    printf("pd03 = %D(5,5)\n", pd03);
  }
  return(0);
}

Output

First time :-------------------------------
Enter three fixed-point decimal number
  (15,4) (10,2) (5,5)
12345678901.2345 -987.6 .24680
pd01 = 12345678901.2345
pd02 = -987.60
pd03 = 0.24680
 
Second time :------------------------------
Enter three fixed-point decimal number
  (15,4) (10,2) (5,5)
123456789013579.24680 123.4567890 987
pd01 = 12345678901.3579
pd02 = 123.45
pd03 = 0.98700

The next example opens the file myfile.dat for reading and then scans this file for a string, a long integer value, a character, and a floating-point value.

#include <stdio.h>
#define  MAX_LEN  80
 
int main(void)
{
   FILE *stream;
   long l;
   float fp;
   char s[MAX_LEN + 1];
   char c;
 
   stream = fopen("myfile.dat", "r");
 
   /* Put in various data. */
   fscanf(stream, "%s", &s[0]);
   fscanf(stream, "%ld", &l);
   fscanf(stream, "%c", &c);
   fscanf(stream, "%f", &fp);
 
   printf("string = %s\n", s);
   printf("long double = %ld\n", l);
   printf("char = %c\n", c);
   printf("float = %f\n", fp);
}

Output

If myfile.dat contains abcdefghijklmnopqrstuvwxyz 343.2, the expected output is:

string = abcdefghijklmnopqrstuvwxyz
long double = 343
char = .
float = 2.000000

The following example uses the sscanf function to read various data from string tokenstring and then displays the data.

#include <stdio.h>
#define  SIZE  81
 
int main(void)
{
char *tokenstring = "15 12 14";
int i;
float fp;
char s[SIZE];
char c;
 
   /* Input various data                              */
   printf("No. of conversions=%d\n",
      sscanf(tokenstring, "%s %c%d%f", s, &c, &i, &fp));
 
   /* If there were no space between %s and %c,       */
   /* sscanf would read the first character following */
   /* the string, which is a blank space.             */
 
   /* Display the data */
   printf("string = %s\n",s);
   printf("character = %c\n",c);
   printf("integer = %d\n",i);
   printf("floating-point number = %f\n",fp);
}

Output

No. of conversions = 4
string = 15
character = 1
integer = 2
floating-point number = 14.000000

Related Information

fprintf, printf, sprintf-Format and Write Data.

See Appendix E, Programming Support for the TPF File System for more information about TPF File System C Functions.