C_格式化输入输出

C_格式化输入输出
BarbecueC_格式化输入/输出
输入/输出模型
由于硬件设备速度:CPU>>内存>>IO设备
为了平衡内存和 IO 设备之间的速度差异,会在内存中设置缓冲区(buffer),其中就有标准输入缓冲区 (stdin) 和标准输出缓冲区 (stdout)等。
printf函数
printf
函数的作用:显示格式串中的内容,并用后面表达式的值替换格式串中的转换说明。
1 | printf(格式字符串, 表达式1, 表达式2, ...); |
格式串中包含普通字符和转换说明。其中,普通字符会原样显示,转换说明则会替换为后面表达式的值。如:
1 | int i, j; |
printf
函数可以将其它类型的数据转换成字符数据,并输出到stdout
缓冲区中。
转换说明
转换说明可以对输出格式进行精确的控制。
转换说明的格式为: %m.pX
或 %-m.pX
,其中 m
和 p
都是整数常量,而 X
是字母。m
和 p
都是可选的;如果省略 p
,则小数点也要省略。如:
1 | %10.2f, %10f, %.2f, %f |
最小字段宽度 (minimum field width) m 指定了要显示的最少字符数量。
如果显示值所需的字符数少于 m,会在值前面添加额外的空格(右对齐)。例如,转换说明%4d
将以 •123
的形式显示 123
(•
代表空格)。
如果显示值所需的字符数多于m,会自动扩展为所需的大小,不会丢失数字。因此, %4d
将以 12345
的形式显示12345
。m前面的负号会导致值左对齐,%-4d
将以 123•
的形式显示123
。
精度 (precision) p 的含义依赖于转换说明符 X 的选择。常用的转换说明符有以下几个:
%d
: 表示十进制整数。p 表示待显示数字的最小个数 (必要时在数字前面补 0);如果省略 p,则默认为1。%f
: 表示“定点十进制”形式的浮点数。p 表示小数点后数字的个数 (默认为 6)。如果 p 为 0,则不显示小数点。%c
: 用于字符%s
: 用于字符串%p
: 指针的地址%m
: 报告上一个错误的描述。%n
: 存储前面参数输出字符的数量。%hh
: 用于char
类型。%Lf
: 用于long double
类型,以长双精度浮点数格式输出。%o
: 用于八进制整数%u
: 用于无符号十进制整数%i
: 有符号十进制、八进制、或十六进制整数(根据输入的前缀)%x
或%X
: 用于无符号十六进制整数,%x
表示小写字母,%X
表示大写字母%a
或%A
: 浮点数的十六进制浮点表示法,%a
表示小写字母,%A
表示大写字母。%e
或%E
: 用于以指数形式表示的浮点数,%e
表示小写字母,%E
表示大写字母%g
或%G
: 用于浮点数,根据值的大小自动选择%f
或%e
,%g
表示小写字母,%G
表示大写字母%ll
、%j
、%z
、%t
: 用于long long
、intmax_t
、size_t
、ptrdiff_t
类型的整数,分别表示长长整数、最大整数类型、大小类型、指针差异类型。
1 | int main(void) |
scanf函数
scanf
函数的作用:根据格式串读取 stdin 中的字符,并将字符转换成指定类型的数据后,写到后面表达式所指定的位置。
1 | scanf(格式串, 表达式1, 表达式2, ...); |
在绝大多数情况下, scanf
函数的格式串中只包含转换说明:
1 | int i, j; |
值得注意的是,通常会在后面变量的前面加 & 符号(取地址运算符),但并不是必须的。
scanf函数的工作原理
scanf
函数本质上是一个”模式匹配”函数,试图把 stdin
中的字符与格式串匹配。
scanf
函数会从左到右依次匹配格式串中的每一项。如果匹配数据项成功,那么scanf
函数会继续处理格式串的剩余部分;如果匹配不成功, scanf
函数将不再处理格式串的剩余部分,而会立刻返回。
scanf
函数的格式串中的每一项都表示一个匹配规则,其中:
%d
: 忽略前置的空白字符 (包括空格符、水平和垂直制表符、换页符和换行符),然后匹配十进制的整数。%f
: 忽略前置的空白字符,然后匹配浮点数。
注意:当**scanf函数
**遇到一个不属于当前项的字符时,它不会读取该字符。在下一次读取输入时,才会读取该字符。如果scanf输入后没有清理缓冲区,下次读写很可能错误
1 | scanf("%d%d%f%f", &i, &j, &x, &y); |
scanf
可以从stdin
缓冲区中读取字符数据,然后转换成其它类型的数据,并写到后面表达式所指定的位置。
格式串中的普通字符
scanf
函数的格式串中也可以包含普通字符,普通字符也用来表示匹配规则。
空白字符:匹配 0 个或多个空白字符。
其它字符:精确匹配(是什么字符就匹配什么字符)。
1
2
3假设格式串是: "%d/%d"
输入1: •5/•96
输入2: •5•/•96
不要混淆printf函数和scanf函数
虽然 scanf
函数调用和 printf
函数调用看起来很相似,但这两个函数之间有很大的差异!
一个常见的错误是:调用
printf
函数时,在变量的前面加&
。
1 | printf("%d,%d\n", &i, &j); /*** 错误的!!!***/ |
scanf
函数在寻找数据项时,通常会跳过前面的空白字符。所以除了转换说明,格式串通常不包含其它字符。
另一个常见的错误就是:认为 scanf
函数的格式串应该类似于 printf
函数的格式串。
1 | scanf("%d,%d", &i, &j); |