scanf_s、_scanf_s_l、wscanf_s、_wscanf_s_l

从标准输入流中读取格式化数据。 scanf、_scanf_l、wscanf、_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。 如果 format 是一个 NULL 指针,无效参数处理程序将按 参数验证 中所述进行调用。 如果允许执行继续,scanf_s 和 wscanf_s 返回 EOF 并设置 errno 为 EINVAL。

有关这些属性和其他错误代码的更多信息,请参见 errno、_doserrno、_sys_errlist 和 _sys_nerr

备注

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

wscanf_s 是 scanf_s 的宽字符版本;wscanf_s 的 format 参数是宽字符字符串。 如果流在 ANSI 模式中打开,wscanf_s 和 scanf_s 会具有相同的行为。 scanf_s 当前不支持 UNICODE 流的输入。

这些带有_l后缀的函数的版本是相同,除了传递的是区域设置参数而不是当前线程区域设置,。

不同于 scanf 和 wscanf,scanf_s 和 wscanf_s 需要为类型 c、C、s、S 的输入参数或封闭在 [] 中的字符串控件集指定缓冲区域大小。 字符中的缓冲区区域大小将紧跟指针作为其他参数传递给缓冲区或变量。 例如,如果您正读取一个字符串,该字符串的缓冲区区域大小的传递如下所示:

char s[10];

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

缓冲区大小区域包括终止 null。 您可以使用宽度规范字段以确保读取的标记将放入缓冲区。 如果未使用宽度规范字段,而标记读入又太大以致无法容纳在缓冲区中,则该缓冲区将不写入任何内容。

备注

大小参数的类型为 unsigned 而非 size_t。

下面的示例显示缓冲区区域大小参数描述的是最大字符数,而不是字节数。 在对 wscanf_s的调用中,缓冲区类型指示的字符宽度和格式说明符指示的字符的宽度不匹配。

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

S 格式说明符指示使用的字符宽度与该函数支持的默认宽度是“对立的”。 该字符宽度是单字节的,但是该函数支持双字节字符。 此示例读取有9 个单字节宽字符的字符串并且将它们写入一个双字节宽字符缓冲区中 。 该字符当作单字节值;最前面的两个字符存储在 ws[0],第二个两个字符存储在 ws[1],以此类推。

就字符而言,单个字符可能被读取,如下所示:

char c;

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

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

char c[4];

scanf_s("%4c", &c, _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

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

要求

例程

必需的标头

scanf_s, _scanf_s_l

<stdio.h>

wscanf_s, _wscanf_s_l

<stdio.h> 或 <wchar.h>

控制台在 Windows 应用商店 应用程序中不受支持。 与控制台 stdin、stdout 和 stderr 关联的标准流句柄必须重定向,然后 C 运行时函数才可以在 Windows 应用商店 应用程序中使用它们。 有关其他兼容性信息,请参见兼容性

示例

// 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, _countof(s), ws, _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, _countof(s), ws, _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

  

.NET Framework 等效项

请参见

参考

浮点支持

流 I/O

区域设置

fscanf、_fscanf_l、fwscanf、_fwscanf_l

printf、_printf_l、wprintf、_wprintf_l

sprintf、_sprintf_l、swprintf、_swprintf_l、__swprintf_l

sscanf、_sscanf_l、swscanf、_swscanf_l