scanf_s、_scanf_s_l、wscanf_s、_wscanf_s_lscanf_s, _scanf_s_l, wscanf_s, _wscanf_s_l

读取标准输入流中的格式化数据。Reads formatted data from the standard input stream. 这些版本的 scanf、_scanf_l、wscanf、_wscanf_l 具有安全增强功能,如 CRT 中的安全功能所述。These versions of scanf, _scanf_l, wscanf, _wscanf_l have security enhancements, as described in Security Features in the CRT.

语法Syntax

int scanf_s(
   const char *format [,
   argument]...
);
int _scanf_s_l(
   const char *format,
   locale_t locale [,
   argument]...
);
int wscanf_s(
   const wchar_t *format [,
   argument]...
);
int _wscanf_s_l(
   const wchar_t *format,
   locale_t locale [,
   argument]...
);

参数Parameters

formatformat
格式控制字符串。Format control string.

实际argument
可选参数。Optional arguments.

localelocale
要使用的区域设置。The locale to use.

返回值Return Value

返回已成功转换和分配的字段数。Returns the number of fields successfully converted and assigned. 返回值不包括已读取但未分配的字段。The return value doesn't include fields that were read but not assigned. 如果返回值为0,则表示未分配任何字段。A return value of 0 indicates no fields were assigned. 对于错误,返回值为EOF ; 或者,如果在第一次尝试读取字符时找到文件尾字符或字符串末尾字符,则为。The return value is EOF for an error, or if the end-of-file character or the end-of-string character is found in the first attempt to read a character. 如果format指针,则将调用无效参数处理程序,如参数验证中所述。If format is a NULL pointer, the invalid parameter handler is invoked, as described in Parameter Validation. 如果允许执行继续,则scanf_sWscanf_s将返回EOF并将errno设置为EINVALIf execution is allowed to continue, scanf_s and wscanf_s return EOF and set errno to EINVAL.

有关这些及其他错误代码的信息,请参阅 errno、_doserrno、_sys_errlist 和 _sys_nerrFor information about these and other error codes, see errno, _doserrno, _sys_errlist, and _sys_nerr.

备注Remarks

Scanf_s函数从标准输入流( stdin)中读取数据,并将其写入参数The scanf_s function reads data from the standard input stream, stdin, and writes it into argument. 每个参数都必须是指向与格式的类型说明符对应的变量类型的指针。Each argument must be a pointer to a variable type that corresponds to the type specifier in format. 如果在重叠的字符串之间发生复制,则此行为不确定。If copying occurs between strings that overlap, the behavior is undefined.

wscanf_sscanf_s的宽字符版本;wscanf_s格式参数是宽字符字符串。wscanf_s is a wide-character version of scanf_s; the format argument to wscanf_s is a wide-character string. 如果在 ANSI 模式下打开流,则wscanf_sscanf_s的行为相同。wscanf_s and scanf_s behave identically if the stream is opened in ANSI mode. scanf_s当前不支持 UNICODE 流的输入。scanf_s doesn't currently support input from a UNICODE stream.

具有 _l后缀的这些函数的版本是相同的,只不过它们使用区域设置参数而不是当前线程区域设置。The versions of these functions that have the _l suffix are identical, except they use the locale parameter instead of the current thread locale.

scanfwscanf不同, scanf_swscanf_s要求你为一些参数指定缓冲区大小。Unlike scanf and wscanf, scanf_s and wscanf_s require you to specify buffer sizes for some parameters. 指定所有ccss或字符串控制集 [] 参数的大小。Specify the sizes for all c, C, s, S, or string control set [] parameters. 以字符作为附加参数传递的缓冲区大小。The buffer size in characters is passed as an additional parameter. 它紧跟在指向缓冲区或变量的指针后面。It immediately follows the pointer to the buffer or variable. 例如,如果您正在读取一个字符串,则将传递该字符串的缓冲区大小,如下所示:For example, if you're reading a string, the buffer size for that string is passed as follows:

char s[10];
scanf_s("%9s", s, (unsigned)_countof(s)); // buffer size is 10, width specification is 9

缓冲区大小包括终端 null。The buffer size includes the terminal null. 您可以使用宽度规范字段来确保读入的令牌适合缓冲区。You can use a width specification field to ensure the token that's read in fits into the buffer. 如果某个令牌太大而无法容纳,则不会向该缓冲区写入任何内容,除非存在宽度规范。When a token is too large to fit, nothing is written to the buffer unless there's a width specification.

备注

大小参数的类型为无符号类型,而不是size_tThe size parameter is of type unsigned, not size_t. 使用静态强制转换将size_t值转换为64位生成配置的无符号值。Use a static cast to convert a size_t value to unsigned for 64-bit build configurations.

Buffer size 参数描述了最大字符数,而不是字节数。The buffer size parameter describes the maximum number of characters, not bytes. 在此示例中,缓冲区类型的宽度与格式说明符的宽度不匹配。In this example, the width of the buffer type doesn't match the width of the format specifier.

wchar_t ws[10];
wscanf_s(L"%9S", ws, (unsigned)_countof(ws));

S格式说明符表示使用该函数支持的默认宽度 "相反" 的字符宽度。The S format specifier means use the character width that's "opposite" the default width supported by the function. 字符宽度是单字节,而函数支持双字节字符。The character width is single byte, but the function supports double-byte characters. 此示例读取一个最多包含9个单字节宽度字符的字符串,并将其放入一个双字节宽度字符缓冲区。This example reads in a string of up to nine single-byte-wide characters and puts them in a double-byte-wide character buffer. 这些字符被视为单字节值;头两个字符存储在 ws[0] 中,紧接着的两个字符存储在 ws[1] 中,依此类推。The characters are treated as single-byte values; the first two characters are stored in ws[0], the second two are stored in ws[1], and so on.

此示例读取单个字符:This example reads a single character:

char c;
scanf_s("%c", &c, 1);

读取非 null 终止的字符串的多个字符时,将同时使用整数规范和缓冲区大小。When multiple characters for non-null-terminated strings are read, integers are used for both the width specification and the buffer size.

char c[4];
scanf_s("%4c", c, (unsigned)_countof(c)); // not null terminated

有关详细信息,请参阅 scanf 宽度规范For more information, see scanf Width Specification.

一般文本例程映射Generic-Text Routine Mappings

TCHAR.H 例程TCHAR.H routine 未定义 _UNICODE 和 _MBCS_UNICODE & _MBCS not defined 已定义 _MBCS_MBCS defined 已定义 _UNICODE_UNICODE defined
_tscanf_s_tscanf_s scanf_sscanf_s scanf_sscanf_s wscanf_swscanf_s
_tscanf_s_l_tscanf_s_l _scanf_s_l_scanf_s_l _scanf_s_l_scanf_s_l _wscanf_s_l_wscanf_s_l

有关详细信息,请参阅格式规范字段:scanf 和 wscanf 函数For more information, see Format Specification Fields: scanf and wscanf Functions.

要求Requirements

例程所返回的值Routine 必需的标头Required header
scanf_s_scanf_s_lscanf_s, _scanf_s_l <stdio.h><stdio.h>
wscanf_s_wscanf_s_lwscanf_s, _wscanf_s_l <stdio.h> 或 <wchar.h><stdio.h> or <wchar.h>

通用 Windows 平台(UWP)应用中不支持控制台。The console isn't supported in Universal Windows Platform (UWP) apps. 标准流处理stdinstdoutstderr必须重定向,然后 C 运行时函数才能在 UWP 应用中使用它们。The standard stream handles stdin, stdout, and stderr must be redirected before C run-time functions can use them in UWP apps. 有关其他兼容性信息,请参阅 兼容性For additional compatibility information, see Compatibility.

示例Example

// crt_scanf_s.c
// This program uses the scanf_s and wscanf_s functions
// to read formatted input.

#include <stdio.h>
#include <stdlib.h>

int main( void )
{
   int      i,
            result;
   float    fp;
   char     c,
            s[80];
   wchar_t  wc,
            ws[80];

   result = scanf_s( "%d %f %c %C %s %S", &i, &fp, &c, 1,
                     &wc, 1, s, (unsigned)_countof(s), ws, (unsigned)_countof(ws) );
   printf( "The number of fields input is %d\n", result );
   printf( "The contents are: %d %f %c %C %s %S\n", i, fp, c,
           wc, s, ws);
   result = wscanf_s( L"%d %f %hc %lc %S %ls", &i, &fp, &c, 2,
                      &wc, 1, s, (unsigned)_countof(s), ws, (unsigned)_countof(ws) );
   wprintf( L"The number of fields input is %d\n", result );
   wprintf( L"The contents are: %d %f %C %c %hs %s\n", i, fp,
            c, wc, s, ws);
}

当提供此输入时,该程序将生成以下输出:This program produces the following output when given this input:

71 98.6 h z Byte characters
36 92.3 y n Wide characters
The number of fields input is 6
The contents are: 71 98.599998 h z Byte characters
The number of fields input is 6
The contents are: 36 92.300003 y n Wide characters

请参阅See also

浮点支持Floating-Point Support
流 I/OStream I/O
区域设置Locale
fscanf、_fscanf_l、fwscanf、_fwscanf_lfscanf, _fscanf_l, fwscanf, _fwscanf_l
printf、_printf_l、wprintf、_wprintf_lprintf, _printf_l, wprintf, _wprintf_l
sprintf、_sprintf_l、swprintf、_swprintf_l、__swprintf_lsprintf, _sprintf_l, swprintf, _swprintf_l, __swprintf_l
sscanf、_sscanf_l、swscanf、_swscanf_lsscanf, _sscanf_l, swscanf, _swscanf_l