scanf 和 printf
scanf 和 printf
scanf和 printf 都是系统自带的函数,在头文件 stdio.h 中定义的。我们要使用 printf 和 scanf,就必须先让编译器理解它们 。用 #include 命令,我们就可以调用文件 stdio.h 的函数scanf和 printf 。
stdio.h名为标准输入输出文件,源于standard input & output。而.h为头文件的后缀。
1. printf
1.1 基本用法
printf 的作用是将参数文本输出到屏幕。它名字里的 f 代表 format (格式化),表示可以定制输出文本的内容。
#include <stdio.h>
int main()
{
printf("Hello World");
return 0;
}
上面命令会在屏幕上输出一行“Hello World”。
运行结束后,光标就停留在输出结束的地方,不会自动换行。
为了让鼠标的光标移到下一行的开头,我们可以在输出文本的结尾,添加一个换行符 \n .
#include <stdio.h>
int main()
{
printf("Hello World\n");
return 0;
}
1.2 占位符
printf 可以在输出文本中指定占位符。
占位符的位置可以被其他值代入。
printf 的参数与占位符是一一对应关系。如果有n个占位符, printf 的参数就有n+1个,第一个参数为格式字符串,用于放置占位符。如果参数少于对应的占位符, printf 可能会输出内存中的任意值。
printf 的占位符有很多种,与C语言的数据类型相对应。下面列出常见的占位符:
%a:十六进制浮点数,字母输出为小写。%A:十六进制浮点数,字母输出为大写。%c:字符。%d:有符号的十进制整数。%e:使用科学计数法的浮点数,指数部分的 e 为小写。%E:使用科学计数法的浮点数,指数部分的 E 为大写。%i:整数,基本等同于 %d 。%f:小数(包含 float 类型和 double 类型)。%g:6个有效数字的浮点数。整数部分⼀旦超过6位,就会自动转为科学计数法,指数部分的 e
为小写。%G:等同于 %g ,唯⼀的区别是指数部分的 E 为大写。%hd:十进制 short int 类型。%ho:八进制 short int 类型。%hx:十六进制 short int 类型。%hu:unsigned short int 类型。%ld:十进制 long int 类型。%lo:八进制 long int 类型。%lx:十六进制 long int 类型。%lu:unsigned long int 类型。%lld:十进制 long long int 类型。%llo:八进制 long long int 类型。%llx:十六进制 long long int 类型。%llu:unsigned long long int 类型。%Le:科学计数法表示的 long double 类型浮点数。%Lf:long double 类型浮点数。%n:已输出的字符串数量。该占位符本⾝不输出,只将值存储在指定变量之中。%o:八进制整数。%p:指针。%s:字符串。%u:无符号整数(unsigned int)。%x:十六进制整数。%zd:size_t 类型。%%:输出⼀个百分号。
1.3 输出格式
printf 可以定制占位符的输出格式。
1.3.1 限定宽度
printf 允许限定占位符的最小宽度。
#include<stdio.h>
int main()
{
printf("%5d", 123);//输出结果为“ 123”
return 0;
}
%5d表示这个占位符的宽度至少为5位。如果不满5位,对应的值的前面会添加空格。
输出的值默认为右对齐,即输出内容前面会有空格;如果希望改成左对齐,可以在占位符的 % 的后面插入一个 - 。
#include<stdio.h>
int main()
{
printf("%-5d", 123);//输出结果为“123 ”
return 0;
}
对于小数,这个限定符会限制所有数字的最小显示宽度。
#include<stdio.h>
int main()
{
printf("%12f", 123.4567);//输出结果为“ 123.456700”
return 0;
}
%12f 表示输出的浮点数至少要占据12位。由于小数的默认显示精度为小数点后6位,所以输出结果的头部会添加2个空格
1.3.2 总是显示正负号
一般来说, printf 不对正数显示正号,只对负数显示负号。如果想在正数也输入正号,可以在占位符的 % 后面加一个 + 。
#include<stdio.h>
int main()
{
printf("%+d", 12);//输出 +12
printf("%+d", -12);//输出 -12
return 0;
}
+ 对正负值没有影响
1.3.3 限定小数位数
输出小数时,有时候希望能限制小数的位数。
#include<Stdio.h>
int main()
{
printf("%.2f", 0.5);//输出为 0.50
return 0;
}
希望小数后面只保留两位小数,占位符写成 %.2f
#include<Stdio.h>
int main()
{
printf("%.2f", 123.456);//输出为 123.46
return 0;
}
限定的位数小于实际的最小位数,会四舍五入。
限定小数位数可以和限定宽度占位符一起使用。
#include<stdio.h>
int main()
{
printf("**%6.2f**", 0.5);//输出为" 0.50"
return 0;
}
限定最小宽度和和小数位数都可以用*代替,通过printf的参数传入。
#include<stdio.h>
int main()
{
printf("%*.*f", 6, 3, 1.23);//输出为" 1.230"
//等同于printf("%6.3f", 1.23)
return 0;
}
1.3.4 输出部分字符串
%s 占位符用来输出字符串,默认是全部输出。如果只想输出开头部分,那么可以用 %.[m]f 指定输出的长度。其中 [m] 代表一个数字,表示所需要输出的长度。
#include<stdio.h>
int main()
{
printf("%.5s", "hello world");//输出"hello"
return 0;
}
2. scanf
2.1 基本用法
scanf 用于读取用户键盘的输出。
#include<stdio.h>
int main()
{
int a = 0;
scanf("%d", &a);
printf("%d", a);
return 0;
}
它的第一个参数为格式字符串,里面放置占位符,用于表明需要输入的数据类型。其余参数用于存放用户输入符变量。格式字符串中有多少的占位符,就有多少个变量。
变量的前面必须加上 & (指针变量除外),因为 scanf 传递的不是址,而是地址。即将变量 i 的地址指向用户输入的值。
输入多个变量:
scanf("%d%d%f%f", &i, &j, &x, &y);
scanf 处理字符占位符的时候,会自动过滤空白字符,包括空格,制表符,换行符等。
用户使用回车键将输入分成几部分,也不影响解读。
scanf 处理数据的原理是:用户的输入先放入缓存,等到按下回车键后,按照占位符对缓存进行解读。
解读用户输入时,会从上一次解读遗留的第一个字符开始,直到读完缓存,或者遇到第一个不符合条件的字符。
#include<Stdio.h>
int main()
{
int x = 0;
float y = 0;
//用户输入" -13.45e12# 0"
scanf("%d", &x);
printf("%d\n", x);//输出-13
scanf("%f", &y);
printf("%f", y);//输出449999994880.000000
return 0;
}
scanf读取用户输入时, %d 会忽略起首的空格,从 - 处开始获取数据,读到 -13 为止,因为后面的 . 对于 %d 不属于有效字符。
第二次调用 scanf ,会从上一次停止解读的地方继续往下读取。此时读取的第一个字符为 . ,由于对应的占位符为 %f ,因此读取的字符串为 .45e12 ,是0.45×10¹²次的意思。
2.2 scanf 的返回值
scanf 的返回值是一个整数,表示成功读取的变量个数。
如果没有读取任何项,或者匹配失败,则返回 0 。如果在成功读取任何数据之前,发生的读取错误或者读取到文件结尾,则返回EOF(end of file),即-1 。
#include<stdio.h>
int main()
{
int a = 0;
int b = 0;
float c = 0.0f;
int r = scanf("%d %d %d", &a, &b, &c);
printf("%d %d %d\n", a, b, c);
printf("%d", r);//输出3
return 0;
}
如果输入两个数以后,按 ctrl+z ,提前结束输入:

在VS环境中按三次ctrl+z (其他编译器中一次即可),结束输入,我们可以看到r是2,即正确读取两个数据。
如果一个数字都不输入,直接按三次ctrl+z ,输出的r是-1,即EOF。

2.3 占位符
scanf 中的占位符与 printf 基本一致。
常见占位符如下:
%c:字符。%d:整数。%f: float 类型浮点数。%lf: double 类型浮点数。%Lf: long double 类型浮点数。%s:字符串。%[]:在⽅括号中指定⼀组匹配的字符(⽐如 %[0-9] ),遇到不在集合之中的字符,匹配将会
停止。
上面所有的占位符中,除了 %c 以外,都会自动忽略起首的空白字符。
%c 不忽略空白字符,总是返回当前的起一个字符,无论该字符是否为空格。
如果要强制跳过字符前的空白字符,可以写成 scanf(" %c", &a) ,即在 %c 前加上一个空格,表示跳过零个或多个空白字符。
%s 并不能简单的等同于字符串。它的规则是:从当前的第一个非空白字符开始读起,直到遇到空白字符(即空格、换行符、制表符)为止,并在字符串最后存储一个空字符 \0 。
因此 %s 不适合读取可能包含空格的字符串。
scanf 将字符串读入字符数组时,不会检测字符串是否超过了数组长度。所以,在储存字符串时,可能会超出数组的边界。因此,使用 %s 时,可以指定读入字符串的最长长度,即写成 %[m]s ,其中 [m] 是一个整数,表示读取字符串的最长长度,后面的字符将被丢弃。
#include<Stdio.h>
int main()
{
char arr[10];
scanf("%10s", arr);
return 0;
}
%10s 表示最多读取10个字符,给 \0 留空间
2.4 赋值忽略符
有时,用户的输入可能不符合预定的格式。
#include<stdio.h>
int main()
{
int year = 0;
int mouth = 0;
int day = 0;
scanf("%d-%d-%d", &year, &mouth, &day);
printf("%d %d %D", year, mouth, day);
return 0;
}
如果输入2021-1-01, scanf 就会正确解读出年、月、日。但如果输入其他格式,如2021/1/01, scanf 就会即系数据失败。
因此, scanf 提供了一个**赋值忽略符 * ,**只要把 * 加在任意占位符的%后面,该占位符就不会返回值,解析后就会被丢弃。
#include<stdio.h>
int main()
{
int year = 0;
int mouth = 0;
int day = 0;
scanf("%d%*c%d%*c%d", &year, &mouth, &day);
printf("%d %d %d", year, mouth, day);
return 0;
}
1698

被折叠的 条评论
为什么被折叠?



