scanf_s, _scanf_s_l, wscanf_s, _wscanf_s_l

读取标准输入流中的格式化数据。 这些版本的 scanf_scanf_lwscanf_wscanf_l 具有安全增强功能,如 CRT 中的安全功能中所述。

语法

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]...
);

参数

format
格式控制字符串。

argument
可选参数。

locale
要使用的区域设置。

返回值

返回已成功转换和分配的字段数。 返回值不包括已读取但未分配的字段。 返回值为 0 表示没有分配任何字段。 出现错误时,或者如果第一次尝试读取字符时发现文件末尾字符或字符串末尾字符,则返回值为 EOF。 如果 formatNULL 指针,则调用无效参数处理程序,如参数验证中所述。 如果允许继续执行,则 scanf_swscanf_s 返回 EOF,并将 errno 设置为 EINVAL

有关这些和其他错误代码的信息,请参阅 errno_doserrno_sys_errlist_sys_nerr

注解

scanf_s 函数从标准输入流 stdin 中读取数据并将其写入 argument中。 每个 argument 必须为指向变量类型的指针,该类型与 format 中的类型说明符对应。 如果在重叠的字符串之间发生复制,则此行为不确定。

wscanf_sscanf_s的宽字符版本; formatwscanf_s 参数是宽字符字符串。 如果在 ANSI 模式下打开流,则 wscanf_sscanf_s 的行为相同。 scanf_s 当前不支持 UNICODE 流的输入。

这些带有 _l 后缀的函数的版本相同,只不过它们使用 locale 参数而不是当前线程区域设置。

scanfwscanf 不同,scanf_swscanf_s 要求为某些参数指定缓冲区大小。 指定所有 cCsS 或字符串控件集 [] 参数的大小。 以字符为单位的缓冲区大小将传递为另一个参数。 它紧随指向缓冲区或变量的指针。 例如,如果你正在读取一个字符串,则将传递该字符串的缓冲区大小,如下所示:

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

缓冲区大小包括终止 null 字符。 可以使用宽度规范字段来确保读入的标记可放入缓冲区中。 当标记过大而无法放入时,除非提供宽度规范,否则不会向缓冲区写入任何内容。

注意

大小参数的类型具有 unsigned,而不具有 size_t。 使用静态强制转换将 size_t 值转换为 unsigned,以进行 64 位生成配置。

缓冲区大小参数描述的是最大字符数而非最大字节数。 在此示例中,缓冲区类型的宽度与格式说明符的宽度不匹配。

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

S 格式说明符表明使用与函数支持的默认宽度“相反的”字符宽度。 该字符宽度是单字节的,而函数支持双字节字符。 此示例可读入最多九个单字节宽度字符的字符串,并将其放入一个双字节宽度字符缓冲区中。 这些字符被视为单字节值;头两个字符存储在 ws[0] 中,紧接着的两个字符存储在 ws[1] 中,依此类推。

以下示例读取单个字符:

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

在读取非 null 终止的字符串的多个字符时,将整数同时用作宽度规范和缓冲区大小。

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

有关详细信息,请参阅 scanf 宽度规范

一般文本例程映射

TCHAR.H 例程 _UNICODE_MBCS 未定义 _MBCS 已定义 _UNICODE 已定义
_tscanf_s scanf_s scanf_s wscanf_s
_tscanf_s_l _scanf_s_l _scanf_s_l _wscanf_s_l

有关详细信息,请参阅格式规范字段:scanfwscanf 函数

要求

例程 必需的标头
scanf_s_scanf_s_l <stdio.h>
wscanf_s_wscanf_s_l <stdio.h><wchar.h>

通用 Windows 平台 (UWP) 应用中不支持控制台。 标准流句柄 stdinstdoutstderr 必须重定向,然后 C 运行时函数才能在 UWP 应用中使用它们。 有关兼容性的详细信息,请参阅 兼容性

示例

// 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);
}

当提供此输入时,该程序将生成以下输出:

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

另请参阅

数学和浮点支持
流 I/O
区域设置
fscanf_fscanf_lfwscanf_fwscanf_l
printf_printf_lwprintf_wprintf_l
sprintf_sprintf_lswprintf_swprintf_l__swprintf_l
sscanf_sscanf_lswscanf_swscanf_l