引言
总结了输入输出函数printf和scanf的一些细节用法,希望对你有帮助
一、二进制的单位速通
在计算机中,字节及其相关单位的换算关系是以2的幂次为基础的,常见的单位换算如下:
1. 位(bit)与字节(Byte):1字节等于8位,即1Byte = 8bit。
2. 字节与千字节(KB):1千字节等于1024字节,即1KB = 1024Byte。
3. 千字节与兆字节(MB):1兆字节等于1024千字节,即1MB = 1024KB。
4. 兆字节与吉字节(GB):1吉字节等于1024兆字节,即1GB = 1024MB。
5. 吉字节与太字节(TB):1太字节等于1024吉字节,即1TB = 1024GB。
6. 太字节与拍字节(PB):1拍字节等于1024太字节,即1PB = 1024TB。
7. 拍字节与艾字节(EB):1艾字节等于1024拍字节,即1EB = 1024PB。
8. 艾字节与泽字节(ZB):1泽字节等于1024艾字节,即1ZB = 1024EB。
9. 泽字节与尧字节(YB):1尧字节等于1024泽字节,即1YB = 1024ZB。
1Byte = 8bit。
1KB = 1024Byte。
1MB = 1024KB。
1GB = 1024MB。
1TB = 1024GB。
1PB = 1024TB。
1EB = 1024PB。
1ZB = 1024EB。
1YB = 1024ZB。
在实际应用中,硬盘、U盘等存储设备的制造商有时会采用1000进制来标注容量,如1GB = 1000MB,这与计算机中的换算有所不同,使用时需注意区分。
二、printf()和scanf()的详解
先给出文档,对英语能力有一定的要求,看不懂,没关系,下面的文章仔细看。
printf()的文档:
scanf - C++ Reference (cplusplus.com)https://legacy.cplusplus.com/reference/cstdio/scanf/?kw=scanf
1.printf
printf() 的作用是将参数文本输出到屏幕。它名字里面的 f 代表格式化(format)表示可以定制输出文本的格式。
printf()是在标准库的头文件stdio.h定义的。使用这个函数之前,必须在源码文件头部引入这
个头文件
#include<stdio.h> int main() { printf("hello word"); return 0; }
还是这个经典的程序。
注意:printf() 不会在行尾自动添加换行符,运行结束后,光标就停留在输出结束的地方,不会自动换行。
为了让光标移到下一行的开头,可以在输出文本的结尾,添加一个换行符:\n
#include<stdio.h> int main() { printf("hello word\n"); return 0; }
1.1占位符
要讲清楚printf()和scanf()这两个函数。必须先了解占位符
printf() 可以在输出文本中指定占位符。
所谓“占位符”,就是这个位置可以用其他值代入。
#include<stdio.h>
int main()
{
printf("There are %d people\n",4);
//这里的4,可以换成其他的整形
return 0;
}
上面示例中,There are %d people\n 是输出文本,里面的 %d 就是占位符,表示这个位置要用其他值来替换。占位符的第一个字符一律为百分号 % ,第⼆个字符表示占位符的类型,%d表示这里代入的值必须是⼀个整数。里面的 4,可以换成其他的整形。
#include<stdio.h> int main() { printf("There are %d people, one of is %s\n", 4,"zhangsan"); return 0; }
这段代码里面的%s,表示代入的是一个字符串,所以这个printf()的第二个参数就必须是字符串
同时,这段代码中也可以看出,输出文本里面是可以使用多个占位符的,但占位符与后面的对应的值必须一一对应,比如:不能用%d,来接受字符串类型,即其他类型。
注意: printf() 参数与占位符是⼀⼀对应关系,如果有 n 个占位符,printf()的参数就应该有n + 1 个。如果参数个数少于对应的占位符, printf() 的参数就应该有 printf() 可能会输出内存中的任意值。
1.2占位符的列举
printf() 的占位符有许多种类,与C语言的数据类型相对应。下面按照字母顺序,列出常用的占位符,方便查找
占位符————————介绍• %a :⼗六进制浮点数,字母输出为小写。
• %A :⼗六进制浮点数,字母输出为大写。
• %c :字符。
• %d :⼗进制整数。
• %e :使⽤科学计数法的浮点数,指数部分的 e 为小写。
• %E :使⽤科学计数法的浮点数,指数部分的 E 为大写。
• %i :整数,基本等同于 %d 。
• %f :⼩数(包含 float 类型和 double 类型)。//float%f double-%lf
• %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 :⽆符号整数(unsignedint)。
• %x :⼗六进制整数。 • %zd : size_t 类型。
• %% :输出⼀个百分号。
1.3输出格式
printf() 可以定制占位符的输出格式。
1.3.1 限制宽度
#include<stdio.h>
int main()
{
printf("%5d\n", 123); // 输出" 123"
return 0;
}
上面示例中, %5d 表示这个占位符的宽度至少为5位。如果不满5位,对应的值的前面会添加空格。 输出的值默认是右对齐,即输出内容前面会有空格;如果希望改成左对齐,在输出内容后面添加空格,可以在占位符的 % 的后面插入一个 - (负)号。
#include<stdio.h>
int main()
{
printf("%-5d", 123);
printf("456");
// 输出"123 456"
return 0;
}
上面示例中,输出内容 123 的后面添加了空格。
#include<stdio.h>
int main()
{
printf("%12f\n", 123.45);
return 0;
}
上面示例中,%12f 表示输出的浮点数最少要占据12位。由于小数的默认显示精度是小数点后6位, 23.45 输出结果的头部会添加2个空格。
1.3.2 总是显示正负号
#include<stdio.h>
int main()
{
pirntf("%+d\n", 10);
pirntf("%+d\n", -10);
return 0;
}
默认情况下, printf() 不对正数显示 + 号,只对负数显示号。如果想让正数也输出 + 号,可以在占位符的 % 后⾯加⼀个 + 。 上面示例中, %+d 可以确保输出的数值,总是带有正负号。
1.3.3 限定小数位数
#include<stdio.h>
int main()
{
printf("num is %.3f\n", 0.5);
return 0;
}
输出小数时,有时希望限定小数的位数。举例来说,希望小数点后面只保留三位,占位符可以写成 %.3f。如果希望⼩数点后面输出3位(0.500),占位符就要写成%.3f。
这种写法可以与限定宽度占位符,结合使用。
#include<stdio.h> int main() { printf("%6.3f\n", 0.5); return 0; }
上面示例中, %6.2f 表示输出字符串最小宽度为6,小数位数为3。所以,输出字符串的头部有两个空格。
最小宽度和小数位数这两个限定值,都可以用 * 代替,通过 printf() 的参数传入
#include<stdio.h> int main() { printf("%*.*f\n",6, 2, 0.5); return 0; }
上面示例中, %*.*f 的两个星号通过 printf() 的两个参数 6 和3 传⼊。
1.3.4 输出部分字符串
%s 占位符用来输出字符串,默认是全部输出。如果只想输出开头的部分,可以用%.[m]s指定输出的长度,其中 [m] 代表⼀个数字,表示所要输出的长度。
#include<stdio.h>
int main()
{
printf("%.5s\n", "hello world");
return 0;
}
上面示例中,占位符 %.5s 表示只输出字符串“hello world”的前5个字符,即“hello”。
2.scanf
当我们有了变量(下一节讲),我们需要给变量输入值就可以使用的scanf 函数,可以再用printf函数打印在屏幕上
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> int main() { int score = 0; printf("请输入成绩:"); scanf("%d", &score); printf("成绩是:%d\n", score); return 0; }
在VS2022上,VS2022认为scanf不安全,让使用scanf_s函数,可以在代码的最上面写上
#define _CRT_SECURE_NO_WARNINGS
来解决这个问题,至于怎么永久解决这个问题,会单独出一章来讲解
上面这段代码,当我们输入99时,屏幕上会打印出99,一个简单的输入输出程序就被写出来啦。
2.1 基本用法
scanf() 函数用于读取用户的键盘输入。
程序运行到这个语句时,会停下来,等待用户从键盘输⼊。
用户输入数据、按下回车键后, scanf() 就会处理用户的输入,将其存入变量。
它的原型定义在头文件 stdio.h 。
scanf() 的语法跟 printf() 类似。
下面详细介绍一下scanf函数
scanf("占位符(个别占位符与printf的占位符有差异)", 变量的地址(&是取地址符号))
如:int score = 0;
score 的地址是 &score,所以要给score变量赋值,就要传入&score
注意:
scanf中的占位符也要一一对应,在键盘上的输入格式应与scanf()中第一个双引号中的格式保持一样
2.2 scanf的返回值
scanf() 的返回值是⼀个整数,表示成功读取的变量个数。 如果没有读取任何项,或者匹配失败,则返回 0 。 如果在成功读取任何数据之前,发生了读取错误或者遇到读取到文件结尾,则返回常量EOF(-1)。
EOF-endoffile 文件结束标志
可以自己写个代码多试一试,注意:在VS2022中,按三次ctrl + z 才能使程序结束(即遇到文件结尾)使其返回-1;
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
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);
return 0;
}
自己多测试测试,才可以体会到其中的韵味 。
2.3 占位符
scanf()常用的占位符如下:
%c : 字符。
%d :整形。
%f : float 类型浮点数。(特记)
%lf : double 类型浮点数。(特记)
%Lf : long double 类型浮点数。
%s :字符串。
%[] :在方括号中指定⼀组匹配的字符(⽐如 %[0-9]), 遇到不在集合之中的字符,匹配将会停止。
上面所有占位符之中,除了 %c 以外,都会自动忽略起首的空白字符。 %c 不忽略空白字符,总是返回当前第⼀个字符,无论该字符是否为空格。 如果要强制跳过字符前的空白字符,可以写成 scanf(" %c", &ch) ,即%c 前加上一个空格,表示跳过零个或多个空白字符。
下面要特别说⼀下占位符 %s ,它其实不能简单地等同于字符串。它的规则是,从当前第⼀个非空白字符开始读起,直到遇到空白字符(即空格、换行符、制表符等)为止。
因为 %s 不会包含空白字符,所以无法用来读取多个单词,除非多个 %s⼀起使用。这也意味着, scanf() 不适合读取可能包含空格的字符串,比如书名或歌曲名。
另外,scanf()遇到%s占位符,会在字符串变量末尾存储⼀个空字符 \0 。
scanf() 将字符串读入字符数组时,不会检测字符串是否超过了数组长度。所以,储存字符串时, 很可能会超过数组的边界,导致预想不到的结果。为了防止这种情况,使用%s读入字符串时,应指定读入字符串的最长长度,即写成 %[m]s ,其中的[m] 是⼀个整数,表示读取字符串的最大长度,后面的字符将被丢弃。
2.4 赋值忽略符
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> int main() { 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; }
上面示例中,如果用户输入 格式,比如 2025-03-08 ,就会正确解读出年、月、日。问题是用户可能输入其他 2025/03/08 ,这种情况下, scanf() 解析数据就会失败。 为了避免这种情况, scanf() 提供了⼀个赋值忽略符(assignment suppression character) * 。 只要把 * 加在任何占位符的百分号后⾯,该占位符就不会返回值,解析后将被丢弃。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
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;
}
上面示例中, %*c 就是在占位符的百分号后面,加入了赋值忽略符 * ,表示这个占位符没有对应的变量,解读后不必返回。