| Main |< C/C++ Variable, Operator & Type 3 | scanf() and scanf_s() 2 >| Site Index | Download |


 

 

 

 

 

 

 

C LAB WORKSHEET 6

C scanf(), scanf_s() family 1

 

 

 

 

 

 

Items in this page:

 

  1. The scanf() and scanf_s() function family – reading data from standard input.

  2. Tutorial references are: C/C++ intro & brief history, C/C++ data type 1, C/C++ data type 2, C/C++ data type 3 and C/C++ statement, expression & operator 1, C/C++ statement, expression & operator 2 and C/C++ statement, expression & operator 2. More scanf() and its family examples can be found in C formatted input/output.

 

 

 

 

 

 

 

 

 

 

 

 

 

// preprocessor directive

#include <stdio.h>

// another preprocessor directive, means replace all INIT_BALANCE

// occurrences in this program with 250.50

#define INIT_BALANCE 250.50

 

void main(void)

{

   float Deposit;

   // name is an array variable, more on this later...

   // means reserve 65 bytes of storage including terminated

   // string, '\0'

   char  Initial, Name[65];

   // some prompt to user...

   printf("Input name, initial and deposit:\n");

   printf("What is your name? ");

   // read the user input and store the data at...

   scanf("%64s", Name);

   printf("What is your initial? ");

   // don't forget the space before %c!!! else the output

   // will be proceeded to the next line...bug or what?

   // read the user input and store the data at...

   // & means storage/memory address of Initial variable...

   scanf(" %c", &Initial);

   printf("How much your deposit? ");

   // read the user input and store the data at...

   scanf("%f", &Deposit);

   // C4996: scanf and wscanf are deprecated; consider

   // using a secure version, scanf_s and wscanf_s

   // now it is time to read the stored data...

   printf("\nDUMMY REPORT:\n");

   printf(" %c. %s had $%.2f\n", Initial, Name, INIT_BALANCE);

   printf(" Now he has $%.2f\n", (INIT_BALANCE + Deposit));

   printf(" His initial is stored at address %p in the system.\n", &Initial);

   // No need to put the & because an array variable without []

   // is already a pointer...

   printf(" His Name is stored at address %p in the system.\n", Name);

}

Visual C++ Express Edition - C, scanf() and scanf_s() program output sample

The scanf(), _scanf_l(), wscanf() and _wscanf_l()

Item

Description

Function

scanf() family.

Use

Read formatted data from the standard input stream. These functions are deprecated and it is better to use a more secure versions scanf_s(), _scanf_s_l(), wscanf_s(), _wscanf_s_l().

Prototype

  1. int scanf(const char *format [, argument]...);

  2. int _scanf_l(const char *format, locale_t locale [, argument]...);

  3. int wscanf(const wchar_t *format [, argument]...);

  4. int _wscanf_l(const wchar_t *format, locale_t locale [, argument]...);

Parameters

format - Format control string.

argument - Optional arguments.

locale - The locale to use.

Example

scanf("%64s", Name);

Return value

Returns the number of fields successfully converted and assigned; the return value does not include fields that were read but not assigned. A return value of 0 indicates that no fields were assigned.

If format is a NULL pointer, the invalid parameter handler is invoked. If execution is allowed to continue, these functions return EOF and set errno to EINVAL.

Include file

<stdio.h> or <wchar.h> for wscanf(), _wscanf_l()

Remark

The scanf() function reads data from the standard input stream stdin and writes the data into the location given by argument. Each argument must be a pointer to a variable of a type that corresponds to a type specifier in format. If copying takes place between strings that overlap, the behavior is undefined.

When reading a string with scanf(), always specify a width for the %s format (for example, "%32s" instead of "%s"); otherwise, improperly formatted input can easily cause a buffer overrun. Alternately, consider using the secure version scanf_s(), _scanf_s_l(), wscanf_s(), _wscanf_s_l() or fgets().

wscanf() is a wide-character version of scanf(); the format argument to wscanf() is a wide-character string. wscanf() and scanf() behave identically if the stream is opened in ANSI mode. scanf() doesn't currently support input from a UNICODE stream.

The versions of these functions with the _l suffix are identical except that they use the locale parameter passed in instead of the current thread locale.

 

Table 1

%[*] [width] [{h | l | ll | I64 | L}]type

Input

Description

White-space characters

Blank (' '); tab ('\t'); or newline ('\n'). A white-space character causes scanf() to read, but not store, all consecutive white-space characters in the input up to the next non–white-space character. One white-space character in the format matches any number (including 0) and combination of white-space characters in the input.

Non-white-space characters

Except for the percent sign (%). A non–white-space character causes scanf() to read, but not store, a matching non–white-space character. If the next character in the input stream does not match, scanf() terminates.

Format specifications

Introduced by the percent sign (%). A format specification causes scanf() to read and convert characters in the input into values of a specified type. The value is assigned to an argument in the argument list.

 

Table 2.

The width specification

  • The width specification consists of characters between the % and the type field specifier, which may include a positive integer called the width field and one or more characters indicating the size of the field, which may also be considered as modifiers of the type of the field, such as an indication of whether the integer type is short or long. Such characters are referred to as the size prefix. For example scanf("%10d", x)  where 10 is the field width.

The Width Field

  • The width field is a positive decimal integer controlling the maximum number of characters to be read for that field. No more than width characters are converted and stored at the corresponding argument. Fewer than width characters may be read if a whitespace character (space, tab, or newline) or a character that cannot be converted according to the given format occurs before width is reached.

  • The width specification is separate and distinct from the buffer size argument required by the secure versions of these functions (i.e., scanf_s(), wscanf_s(), etc.). In the following example, the width specification is 20, indicating that up to 20 characters are to be read from the input stream. The buffer length is 21, which includes room for the possible 20 characters plus the null terminator:

 

char str[21];

scanf("%20s", str, 21);

The Size Prefix

Size Prefixes for scanf() and wscanf() Format-Type Specifiers

To specify

Use prefix

With type specifier

double

l (el letter)

e, E, f, g, or G

long double (same as double)

L

e, E, f, g, or G

long int

l

d, i, o, x, or X

long unsigned int

l

u

long long

ll

d, i, o, x, or X

short int

h

d, i, o, x, or X

short unsigned int

h

u

__int64

I64

d, i, o, u, x, or X

Single-byte character with scanf()

h

c or C

Single-byte character with wscanf()

h

c or C

Wide character with scanf()

l

c or C

Wide character with wscanf()

l

c, or C

Single-byte – character string with scanf()

h

s or S

Single-byte – character string with wscanf()

h

s or S

Wide-character string with scanf()

l

s or S

Wide-character string with wscanf()

l

s or S

 

Table 3.

scanf_s("%ls", &x, 2);     // read a wide-character string

wscanf_s("%hC", &x, 2);    // read a single-byte character

Reading Undelimited strings

Reading Unterminated strings

Type Characters for scanf() functions

Character

Type of input expected

Type of argument

Size argument in secure version?

c

Character. When used with scanf() functions, specifies single-byte character; when used with wscanf() functions, specifies wide character. White-space characters that are ordinarily skipped are read when c is specified. To read next non–white-space single-byte character, use %1s; to read next non–white-space wide character, use %1ws.

Pointer to char when used with scanf() functions, pointer to wchar_t when used with wscanf() functions.

Required. Size does not include space for a null terminator.

C

Opposite size character. When used with scanf() functions, specifies wide character; when used with wscanf functions, specifies single-byte character. White-space characters that are ordinarily skipped are read when C is specified. To read next non–white-space single-byte character, use %1s; to read next non–white-space wide character, use %1ws.

Pointer to wchar_t when used with scanf functions, pointer to char when used with wscanf() functions.

Required. Size argument does not include space for a null terminator.

d

Decimal integer.

Pointer to int.

No.

i

Decimal, hexadecimal, or octal integer.

Pointer to int.

No.

o

Octal integer.

Pointer to int.

No.

u

Unsigned decimal integer.

Pointer to unsigned int.

No.

x

Hexadecimal integer.

Pointer to int.

No.

e, E, f, g, G

Floating-point value consisting of optional sign (+ or –), series of one or more decimal digits containing decimal point, and optional exponent ("e" or "E") followed by an optionally signed integer value.

Pointer to float.

No.

n

No input read from stream or buffer.

Pointer to int, into which is stored number of characters successfully read from stream or buffer up to that point in current call to scanf functions or wscanf() functions.

No.

s

String, up to first white-space character (space, tab or newline). To read strings not delimited by space characters, use set of square brackets ([ ]), as discussed in scanf() Width Specification.

When used with scanf() functions, signifies single-byte character array; when used with wscanf() functions, signifies wide-character array. In either case, character array must be large enough for input field plus terminating null character, which is automatically appended.

Required. Size includes space for a null terminator.

S

Opposite-size character string, up to first white-space character (space, tab or newline). To read strings not delimited by space characters, use set of square brackets ([ ]), as discussed in scanf() Width Specification.

When used with scanf() functions, signifies wide-character array; when used with wscanf functions, signifies single-byte–character array. In either case, character array must be large enough for input field plus terminating null character, which is automatically appended.

Required. Size includes space for a null terminator.

 

Table 4.

char string1[11], string2[9];

scanf("%10s %8s", string1, 11, string2, 9);

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

To read character as

Use this function

With these format specifiers

single byte

scanf() functions

c, hc, or hC

single byte

wscanf() functions

C, hc, or hC

wide

wscanf() functions

c, lc, or lC

wide

scanf() functions

C, lc, or lC

 

Table 5.

A Secure Version: scanf_s(), _scanf_s_l(), wscanf_s() and _wscanf_s_l()

Item

Description

Function

scanf_s(), _scanf_s_l(), wscanf_s() and _wscanf_s_l()

Use

Read formatted data from the standard input stream. These are versions of scanf(), _scanf_l(), wscanf(), _wscanf_l() with security enhancements.

Prototype

  1. int scanf_s(const char *format [, argument]...);

  2. int _scanf_s_l(const char *format, locale_t locale [, argument]...);

  3. int wscanf_s(const wchar_t *format [, argument]...);

  4. int _wscanf_s_l(const wchar_t *format, locale_t locale [, argument]...);

Parameters

format - Format control string.

argument - Optional arguments.

locale - The locale to use.

Example

scanf_s( "%d %f %c %C %s %S", &i, &fp, &c, 1, &wc, 1, s, 60, ws, 60 );

Return value

Returns the number of fields successfully converted and assigned; the return value does not include fields that were read but not assigned. A return value of 0 indicates that no fields were assigned. The return value is EOF for an error or if the end-of-file character or the end-of-string character is encountered in the first attempt to read a character. If format is a NULL pointer. If execution is allowed to continue, scanf_s() and wscanf_s() return EOF and set errno to EINVAL.

Include file

<stdio.h> or <wchar.h> for wscanf_s(), _wscanf_s_l()

Remark

The scanf_s() function reads data from the standard input stream stdin and writes the data into the location given by argument. Each argument must be a pointer to a variable of a type that corresponds to a type specifier in format. If copying takes place between strings that overlap, the behavior is undefined.

wscanf_s() is a wide-character version of scanf_s(); the format argument to wscanf_s() is a wide-character string. wscanf_s() and scanf_s() behave identically if the stream is opened in ANSI mode. scanf_s() doesn't currently support input from a UNICODE stream.

The versions of these functions with the _l suffix are identical except that they use the locale parameter passed in instead of the current thread locale.

Unlike scanf() and wscanf(), scanf_s() and wscanf_s() require the buffer size to be specified for all input parameters of type c, C, s, S, or [. The buffer size is passed as an additional parameter immediately following the pointer to the buffer or variable. For example, if reading a string, the buffer size for that string is passed as follows:

 

char s[10];

scanf("%9s", s, 10);

 

The buffer size includes the terminating null. A width specification field may be used to ensure that the token read in will fit into the buffer. If no width specification field is used, and the token read is too big to fit in the buffer, nothing will be written to that buffer. In the case of characters, one may read a single character as follows:

 

char c;

scanf("%c", &c, 1);

 

When reading multiple characters for non-null terminated strings, integers are used as the width specification and the buffer size.

 

char c[4];

scanf("%4c", &c, 4); // not null terminated

 

 

Table 6.

 

Parameter Validation

Invalid Parameter Handler Routine

 

 

 

 

 

 

 

 

| Main |< C/C++ Variable, Operator & Type 3 | scanf() and scanf_s() 2 >| Site Index | Download |


The C scanf() and scanf_s() family: Part 1 | Part 2 | Part 3