printf

基本用法

pritnf()的作用是将参数问本输出到屏幕。其中 f 代表 format(格式化),

表示可以限制输出文本的格式。

printf()不会在行尾自动加上换行符

1
2
printf("hello world!");
printf("hello world!");

想要换行的话可以使用 \n 。

1
2
printf("hello world!\n");
printf("hello world!\n");

想要文本内换行也可以使用 \n。

1
printf("hello\n wol\nrd!");

限定宽度

printf()可以限制占位符的最小宽度。

1
2
3
4
printf("%d\n", 123);
printf("%5d\n", 123); // 右对齐
printf("%5d\n", 12345678); // 右对齐
printf("%-5dhaha\n", 123); // 左对齐 这里加上haha 是为了更直观的体现


上述代码中, %5d 表示这个占位符的宽度至少是5个字符。若不满五位,

对应的值前会加上空格。

默认对齐方式是右对齐,如果想要左对齐,加上负号即可。

对于小数,这个限制符会限制所有数字的显示宽度

1
printf("%12f\n", 123.45);

上述代码中,%12f 表示输出的浮点数最少要占12位,由于小数的默认显示

精度是小数点后6位且小数点本身占一位,所以前面多了两个空格。

限定小数位

有时候会希望限制小数位。例如希望显示两位小数,就用 .2%f。

1
2
3
printf("%.2f\n", 1.23456);
printf("%.3f\n", 1.23456);
printf("%.4f\n", 1.23456);

可以和前文中的限制宽度位数的写法结合使用

1
printf("%5.2f\n", 1.2345);

上述写法可以写作一种通式写法

最小宽度和小数位数这两个限定数可以写作*,由printf的参数传入。

1
printf("%*.*f\n", 5,2,1.2345);

输出部分字符串

%s占位符用来输出字符串,默认是全部输出。如果只想输出部分可以进行限制。

1
printf("%.5s\n", "hello world");

scanf

通过库函数 scanf 可以输入值给变量。

1
2
3
4
int num = 0;
printf("请输入数值:> ");
scanf("%d", &num);
printf("%d\n", num);

visual studio 中的scanf

在 visual studio 中默认使用 scanf 时,会不允许使用。

在 visual studio 中,鼓励使用的是 scanf_s。

但是,scanf_s 这个函数是 visual studio 提供的,而并非是C语言标准输入输出

库中的函数,使用该函数会影响代码的可移植性。

可视实际情况选择使用哪个函数。

若要在 visual studio 中使用 scanf 函数,需在整个源文件的首行加上一行代码

1
#define _CRT_SECURE_NO_WARNINGS 1

即可正常使用 scanf 。

1
scanf("%d",&i);

它的第一个参数是一个格式字符串,告诉编译器需要提取的数据是什么类型。

它的其余参数是存放用户输入的变量,格式字符串里面有多少个占位符,

就有多少个变量。

上述代码中 scanf 的第一个参数是 %d , 表示输入的数据是一个整数。

%d 就是一个占位符,&i表示输入的数据存入变量i。

下面是一个多次输入的示例

1
2
3
4
5
6
7
   nt i = 0;
int j = 0;
float x = 0.0f;
float y = 0.0f;
printf("请输入4个操作数\n");
scanf("%d%d%f%f", &i, &j, &x, &y);
printf("i = %d ,j = %d ,x = %f,y = %f", i, j, x, y);

scanf 函数在处理数值占位符时会自动过滤掉空白字符,如空格,制表

符,换行符等。

1
2
3
4
5
6
7
int x;
float y;
// 输入" -13.45e12# 0"
scanf("%d", &x);
printf("%d\n", x);
scanf("%f", &y);
printf("%f\n", y);

上述代码中,输入的是 -13.45e12# 0
那么根据 scanf的读取规则,前面两个空格

自动过滤,读到 - 时开始将数
值存储进入到 x ,读到.时发现不属于整型就停止

读取,变量 x 的值为-13 。从 . 开始读时,scanf 认为是小数便开始往变量 y 中存

储数值,读到 # 时发现不属于浮点型停止读取,此时变量 y 的 值为 0.45 * 10 ^

12。

scanf 的返回值

scanf 的返回值是一个整数,表示成功读取的变量个数。

如果没有读取任何项,或者匹配失败。则返回0。如果在成功任何数据之前,

发生了读取错误或者遇到读取文件末尾,则返回 EOF 。

1
2
3
4
5
6
int a = 0;
int b = 0;
float f = 0.0f;
int r = scanf("%d %d %f", &a, &b, &f);
printf("a=%d b=%d f=%f\n", a, b, f);
printf("r = %d\n", r);


正常输入,返回值就是3.

如果输入两个值就提前就是返回值就是2.

如果都不输入,返回值就是 EOF ,即 -1.

scanf 占位符中的 % s

scanf 中的 %s 不能简单的等同于字符串,他的规则实际上是从当前第一个非空白

字符开始读起,直到遇到空白字符结束。

1
2
3
char arr[10] = { 0 };
scanf("%s", arr);
printf("%s\n", arr);

所以,scanf 不适合读取可能包含空白字符的字符串,比如书名或者歌曲名。

scanf 遇到 %s 占位符时,读取后会给字符串后加上一个 \0 。

scanf 将字符串读入字符数组时,不会检测字符串是否超过了数组长度。这样就

会存在越界的情况。

在使用 %s 占位符时,应指定读入字符串的最大长度,写作%[m]s 的形式, m 是一

个整数,表示读取字符串的最大长度,后面的字符将被丢弃。

1
2
3
char arr[5] = { 0 };
scanf("%5s", arr);
printf("%s\n", arr);

赋值忽略符

1
2
3
4
5
6
int year = 0;
int month = 0;
int day = 0;
scanf("%d-%d-%d", &year, &month, &day);
printf("%d %d %d\n", year, month, day);
return 0;

该代码中,如果输入形式不符合 scanf 中的形式,就会导致解析数据失败。

采用赋值忽略符 * , 即可忽略这个问题。

1
%*[格式占位符]

赋值忽略符必须放在 %和占位符之间。该占位符就不会返回值,解析后将被丢

弃。

1
2
3
4
5
int year = 0;
int month = 0;
int day = 0;
scanf("%d%*c%d%*c%d", &year, &month, &day);
printf("%d %d %d\n", year, month, day);