std::scanf,std::fscanf,std::sscanf

2026-01-11 15:58:59 情怀礼包

C++

Compiler support

Freestanding and hosted

Language

Standard library

Standard library headers

Named requirements

Feature test macros

(C++20)

Language support library

Concepts library

(C++20)

Diagnostics library

Memory management library

Metaprogramming library

(C++11)

General utilities library

Containers library

Iterators library

Ranges library

(C++20)

Algorithms library

Strings library

Text processing library

Numerics library

Date and time library

Input/output library

Filesystem library

(C++17)

Concurrency support library

(C++11)

Execution control library

(C++26)

Technical specifications

Symbols index

External libraries

Input/output library

I/O manipulators

Print functions

(C++23)

C-style I/O

Buffers

basic_streambuf

basic_filebuf

basic_stringbuf

basic_spanbuf

(C++23)

strstreambuf

(

C++98/26*

)

basic_syncbuf

(C++20)

Streams

Abstractions

ios_base

basic_ios

basic_istream

basic_ostream

basic_iostream

File I/O

basic_ifstream

basic_ofstream

basic_fstream

String I/O

basic_istringstream

basic_ostringstream

basic_stringstream

Array I/O

basic_ispanstream

(C++23)

basic_ospanstream

(C++23)

basic_spanstream

(C++23)

istrstream

(

C++98/26*

)

ostrstream

(

C++98/26*

)

strstream

(

C++98/26*

)

Synchronized Output

basic_osyncstream

(C++20)

Types

streamoff

streamsize

fpos

Error category interface

iostream_category

(C++11)

io_errc

(C++11)

C-style I/O

Types and objects

FILE

fpos_t

stdin

stdout

stderr

Functions

File access

fopen

freopen

fclose

fflush

fwide

setbuf

setvbuf

Direct input/output

fread

fwrite

Unformatted input/output

fgetc

getc

fgets

fputc

putc

fputs

getchar

gets

(until C++14)

putchar

puts

ungetc

fgetwc

getwc

fgetws

fputwc

putwc

fputws

getwchar

putwchar

ungetwc

Formatted input

scanf

fscanf

sscanf

vscanf

vfscanf

vsscanf

(C++11)

(C++11)

(C++11)

wscanf

fwscanf

swscanf

vwscanf

vfwscanf

vswscanf

(C++11)

(C++11)

(C++11)

Formatted output

printf

fprintf

sprintf

snprintf

(C++11)

vprintf

vfprintf

vsprintf

vsnprintf

(C++11)

wprintf

fwprintf

swprintf

vwprintf

vfwprintf

vswprintf

File positioning

ftell

fgetpos

fseek

fsetpos

rewind

Error handling

clearerr

feof

ferror

perror

Operations on files

remove

rename

tmpfile

tmpnam

定义于头文件

int

scanf

(

const

char

*

format, ...

)

;

(1)

int

fscanf

(

std::

FILE

*

stream,

const

char

*

format, ...

)

;

(2)

int

sscanf

(

const

char

*

buffer,

const

char

*

format, ...

)

;

(3)

从多种来源读取数据,根据

format

解释数据,并将结果存储到指定位置。

1)

stdin

读取数据。

2)

从文件流

stream

中读取数据。

3)

从以空字符结尾的字符串

buffer

中读取数据。

目录

1

参数

2

返回值

3

复杂度

4

备注

5

示例

6

参见

参数

stream

-

用于读取的输入文件流

buffer

-

指向以空字符结尾的字符串的指针,用于读取数据

format

-

指向以空字符结尾的字符串的指针,指定输入读取格式

...

-

接收参数

format

字符串由以下部分组成

非空白多字节字符(除

%

外):格式字符串中的每个此类字符会从输入流中消耗一个完全相同的字符,如果流中的下一个字符不相等则导致函数执行失败。

空白字符:格式字符串中的任意单个空白字符会消耗输入中所有可用的连续空白字符(通过循环调用

std::isspace

确定)。注意格式字符串中的

"

\n

"

" "

"

\t

\t

"

或其他空白字符之间没有区别。

转换说明符。每个转换说明符具有以下格式:

引导性

%

字符。

(可选)

赋值抑制字符

*

。若存在此选项,函数不会将转换结果赋值给任何接收参数。

(可选)

指定

最大字段宽度

的整数(大于零),即函数在执行当前转换说明符指定的转换时允许消耗的最大字符数。请注意,若未提供宽度参数,

%

s

%

[

可能导致缓冲区溢出。

(可选)

长度修饰符

用于指定接收参数的大小,即实际的目标类型。这将影响转换精度和溢出规则。默认目标类型因各转换类型而异(详见下表)。

转换格式说明符。

以下格式说明符可用:

转换

说明符

说明

期望

参数类型

长度修饰符→

hh

h

l

ll

j

z

t

L

仅自 C++11 起可用→

%

匹配字面量

%

N/A

N/A

N/A

N/A

N/A

N/A

N/A

N/A

N/A

c

匹配一个

字符

或一系列

字符

如果使用宽度说明符,则精确匹配

width

个字符(参数必须指向具有足够空间的数组)。

与 %s 和 %[ 不同,不会向数组追加空字符。

N/A

N/A

char

*

wchar_t

*

N/A

N/A

N/A

N/A

N/A

s

匹配非空白字符序列(即

string

)。

若使用宽度限定符,则最多匹配

width

个字符或遇到首个空白字符即停止(以先到者为准)。

始终在匹配字符外额外存储一个空字符(因此参数数组必须至少有

width+1

字符的存储空间)。

[

set



]

匹配来自字符集

set

的非空字符序列。

若集合的首字符为

^

,则匹配所有不在该集合中的字符。

若集合以

]

^]

开头,则

]

字符也会被包含在集合中。

在非起始位置出现的

-

字符是否表示范围(如

[0-9]

)由实现定义。

若使用了宽度限定符,则最多匹配

width

个字符。

始终在匹配的字符之外额外存储一个空字符(因此参数数组必须至少有

width+1

个字符的空间)。

d

匹配一个

十进制整数

数字格式与

std::strtol

函数所期望的格式相同,其中

10

作为

base

参数的值。

signed

char

*

unsigned

char

*

signed

short

*

unsigned

short

*

signed

int

*

unsigned

int

*

signed

long

*

unsigned

long

*

signed

long

long

*

unsigned

long

long

*

std::

intmax_t

*

std::

uintmax_t

*

std::

size_t

*

std::

ptrdiff_t

*

不适用

i

匹配一个

整数

数字格式与

std::strtol

函数所期望的格式相同,其中

0

作为

base

参数的值(进制由解析的首字符确定)。

u

匹配无符号

十进制整数

数字格式与

std::strtoul

函数所期望的格式相同,其中

10

作为

base

参数的值。

o

匹配无符号

八进制整数

数字格式与

std::strtoul

函数的要求相同,其中

8

作为

base

参数的值。

x

X

匹配无符号

十六进制整数

数字格式与

std::strtoul

函数的要求一致,其中

16

作为

base

参数的值。

n

返回

当前已读取的字符数

不消耗输入。不增加赋值计数。

若格式说明符定义了赋值抑制操作符,则行为未定义。

a

(C++11)

A

(C++11)

e

E

f

F

(C++11)

g

G

匹配

浮点数

数字格式与

std::strtof

所预期的格式相同。

不适用

不适用

float

*

double

*

不适用

不适用

不适用

不适用

long

double

*

p

匹配实现定义的字符序列,用于表示

指针

printf

系列函数应使用

%p

格式说明符生成相同序列。

N/A

N/A

void

**

N/A

N/A

N/A

N/A

N/A

N/A

备注

对于除

n

之外的所有转换说明符,从流中消耗的输入字符序列是:不超过指定字段宽度、且完全符合转换说明符预期或符合其预期序列前缀的最长字符序列。该消耗序列后的首个字符(若存在)将保持未读取状态。若消耗序列长度为零,或消耗序列无法按上述规则完成转换,则出现匹配失败——除非因文件结束、编码错误或读取错误导致无法从流中获取输入,此时属于输入失败。

[

c

n

之外的所有转换说明符,在尝试解析输入前会消耗并丢弃所有前导空白字符(通过调用

std::isspace

判定)。这些被消耗的字符不计入指定的最大字段宽度。

转换说明符

lc

ls

l

[

会执行多字节到宽字符的转换,其过程类似于在转换首个字符前,调用以零初始化的

std::mbstate_t

对象进行

std::mbrtowc

调用。

转换说明符

s

[

除了存储匹配的字符外,始终会存储空终止符。目标数组的大小必须至少比指定字段宽度大1。若使用

%

s

%

[

时未指定目标数组大小,其不安全性等同于

std::gets

固定宽度整数类型

(如

std::int8_t

等)的正确转换规范定义于头文件

中(尽管

SCNdMAX

SCNuMAX

等分别等同于

%

jd

%

ju

等)。

每个转换说明符执行完成后存在一个

顺序点

,这允许将多个字段存储至同一个“接收”变量中。

当解析以指数符号结尾但缺少数字的不完整浮点数值时(例如使用转换说明符

%

f

解析

"100er"

),将消耗序列

"100e"

(可能有效的浮点数的最长前缀),导致匹配错误(消耗的序列无法转换为浮点数),并保留

"r"

。某些现有实现未遵循此规则,会回退至仅消耗

"100"

,留下

"er"

,例如

glibc bug 1765

若转换规范无效,则行为未定义。

返回值

成功接收并赋值的参数数量(若在首个接收参数被赋值前发生匹配失败,则该值可能为零),或

EOF

若在首个接收参数被赋值前发生输入失败。

复杂度

不保证性能。特别需要注意的是,某些

std::sscanf

的实现是

O(N)

的,其中

N

=

std::

strlen

(

buffer

)

[1]

。如需高性能字符串解析,请参阅

std::from_chars

注释

由于大多数转换说明符首先会消耗所有连续的空白字符,因此诸如

std::scanf("%d", &a);

std::scanf("%d", &b);

将读取在不同行输入的两个整数(第二个

%

d

会消耗第一个输入遗留的换行符)或在同一行输入、以空格或制表符分隔的两个整数(第二个

%

d

会消耗空格或制表符)。

The conversion specifiers that do not consume leading whitespace, such as

%

c

, can be made to do so by using a whitespace character in the format string:

std::scanf("%d", &a);

std::scanf(" %c", &c); // 忽略 %d 后的换行符,然后读取一个字符

请注意,某些

std::sscanf

的实现会调用

std::strlen

,这导致其运行时间与整个字符串的长度成线性关系。这意味着如果在循环中调用

std::sscanf

来重复解析字符串前端的值,您的代码可能会以二次方时间运行(

示例

)。

示例

运行此代码

#include

#include

#include

int main()

{

int i, j;

float x, y;

char str1[10], str2[4];

wchar_t warr[2];

std::setlocale(LC_ALL, "en_US.utf8");

char input[] = "25 54.32E-1 Thompson 56789 0123 56ß水";

// 解析方式如下:

// %d: 整数

// %f: 浮点数值

// %9s: 最多9个非空白字符的字符串

// %2d: 两位整数(数字5和6)

// %f: 浮点数值(数字7、8、9)

// %*d: 不存储在任何位置的整数

// ' ': 所有连续空白字符

// %3[0-9]: 最多3位数字的字符串(数字5和6)

// %2lc: 两个宽字符,使用多字节到宽字符转换

const int ret = std::sscanf(input, "%d%f%9s%2d%f%*d %3[0-9]%2lc",

&i, &x, str1, &j, &y, str2, warr);

std::cout << "转换了 " << ret << " 个字段:\n"

"i = " << i << "\n"

"x = " << x << "\n"

"str1 = " << str1 << "\n"

"j = " << j << "\n"

"y = " << y << "\n"

"str2 = " << str2 << std::hex << "\n"

"warr[0] = U+" << (int)warr[0] << "\n"

"warr[1] = U+" << (int)warr[1] << '\n';

}

输出:

转换了 7 个字段:

i = 25

x = 5.432

str1 = Thompson

j = 56

y = 789

str2 = 56

warr[0] = U+df

warr[1] = U+6c34

另请参阅

vscanf

vfscanf

vsscanf

(C++11)

(C++11)

(C++11)

stdin

、文件流或缓冲区读取格式化输入

使用可变参数列表

(函数)

fgets

从文件流获取字符串

(函数)

printf

fprintf

sprintf

snprintf

(C++11)

将格式化输出打印到

stdout

、文件流或缓冲区

(函数)

from_chars

(C++17)

将字符序列转换为整型或浮点型值

(函数)

C 文档

关于

scanf

fscanf

sscanf