C++ 标准库的 C I/O 子集实现 C 风格流输入/输出操作。 <cstdio> 头文件提供通用文件支持并提供有窄和多字节字符输入/输出能力的函数,而 <cwchar>头文件提供有宽字符输入/输出能力的函数。
有格式输入/输出
从 stdin、文件流或缓冲区读取有格式输入
std::scanf,
std::fscanf,
std::sscanf
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
读数据
参数
stream | - | 读取来源的文件流 |
buffer | - | 指向读取数据来源的空终止字符串 |
format | - | 指向指定如何读取输入的空终止字符串的指针。 格式字符串由下列内容组成
|
下列格式指定符可用:
|
对于每个异于 所有异于 转换指定符 转换指定符 定宽整数类型( 在每个转换指定符后有一个序列点;这允许存储多个域到同一“池”变量中。 在分析以无数字指数为结尾的不完整浮点值,如以转换指定符 %f 分析 "100er" 时,消耗序列 "100e" (可能为合法浮点数的最长前缀),并导致匹配错误(被消耗序列不能转换成浮点数),而留下 "r" 。某些既存实现不遵守此规则并回滚,通过消耗 "100" 而留下 "er" ,例如 glibc 漏洞 1765 。 | ||
... | - | 接收的参数 |
返回值
成功赋值的参数数(在首个参数赋值前发生匹配失败的情况下可为零),或若在赋值首个接收的参数前输入失败则为 EOF 。
注意
因为大多数转换指定符首先消耗所有连续空白符,如下代码
std::scanf("%d", &a);
std::scanf("%d", &b);
会读取输入于不同行(第二个 %d 会消耗第一个剩下的换行符)或同一行中为空格或制表符所分隔的(第二个 %d 会消耗空格或制表符)二个整数。
不消耗前导空白符的转换指定符,如 %c ,可通过在格式化字符串中用空白符使得它这么做:
std::scanf("%d", &a);
std::scanf(" %c", &c); // 忽略 %d 后的换行符,然后读一个 char
调用示例
#include <iostream>
#include <clocale>
#include <cstdio>
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[] = u8"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 :二个宽字符,用多字节到宽转换
int ret = std::sscanf(input, "%d%f%9s%2d%f%*d %3[0-9]%2lc",
&i, &x, str1, &j, &y, str2, warr);
std::cout << "Converted " << ret << " fields:\n"
<< "i = " << i << "\nx = " << x << '\n'
<< "str1 = " << str1 << "\nj = " << j << '\n'
<< "y = " << y << "\nstr2 = " << str2 << '\n'
<< std::hex << "warr[0] = U+" << warr[0]
<< " warr[1] = U+" << warr[1] << '\n';
return 0;
}