scanf与printf详解——算法知识竞赛必备

前言

        相信大家在学习期间或多或少都会接触到算法题目,而这时候scanf与printf这两个函数就会显得尤为重要了,如果scanf与printf用不好的话,那我相信写算法题目一定是会非常痛苦的。那么好,就让我们一起来学习一下这两个函数把!


printf 详解

        1. 基本用法

                printf () 的作用在于将参数文本输出到终端。其中末尾的f 表示格式化,可以指定输出文本的格式

int main()
{
    // 最简单的使用方法,直接传递参数
    printf("1111111\n");
    return 0;
}

        2. 占位符

                占位符在scanf与printf中是一个非常重要的概念。printf可以在输出⽂本中指定占位符,等待数据代替占位符输出。

        占位符的特点:占位符的第一个字符一律为百分号(%),第二个字符表示占位符的类型

        printf() 中可以在输出文本中可以指定N个占位符,等待N个指定的值输入进来

        printf() 中的参数与占位符是一一对应的,如果有N个占位符,那么printf() 参数也应该有N个

int main()
{
    //特点:占位符的第一个字符一律为百分号(% ),第二个字符表示占位符的类型

    //Printf() 中可以在输出文本中指定占位符,等待其他指定的值输入进来
    printf("你的期末考试成绩是%d\n", 100);
    printf("你的期末考试成绩是%d\n", 10);

    //Printf() 中可以在输出文本中可以指定N个占位符,等待N个指定的值输入进来
    printf("你的期末考试成绩是%d,你的语文成绩是%d,你的数学成绩是%d\n", 10, 1, 10);
    return 0;
}

                 那么这里就要介绍一下C语言中占位符的种类了:

类型介绍
%a
⼗六进制浮点数,字⺟输出为⼩写
%A

⼗六进制浮点数,字⺟输出为⼤写

%c

字符

%d

⼗进制整数  // int

%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 类型

%%

输出⼀个百分号

                 虽然C语言中的占位符很多,但是我们在日常使用中也不过就那其中几个,无非是:

类型介绍
%c
字符
%d
⼗进制整数  // int
%f
⼩数(包含 float 类型和 double 类型)
%ld
⼗进制 long int 类型
%p
指针(⽤来打印地址)
%s
字符串
%u
⽆符号整数(unsigned int)
%x
⼗六进制整数

        3. 输出格式 

                printf的输出方式可以被定制

                3.1 限定输出宽度

        printf允许限定占位符的最小宽度,需要在占位符(%)后加上一个限定宽度的数字(N)

        如果输出的内容不满N位,对应的值的前⾯会添加空格。输出的值默认是右对⻬ 

int main()
{
    //Printf() 允许限定占位符的最小宽度
    char str[] = "abcdefg";
    printf("%5sefg\n", str);// 输出为" abcd"
    // %5s 表示这个占位符的最小宽度为5,如果不足5位,会使用空格代替
    return 0;
}

        如果希望改成左对⻬,可以在占位符的 % 的后⾯插⼊⼀个 - 号

int main()
{
    //Printf() 允许限定占位符的最小宽度
    char str[] = "abcdefg";
    printf("%5sefg\n", str);// 输出为" abcd"
    // %5s 表示这个占位符的最小宽度为5,如果不足5位,会使用空格代替

    // 代替的空格默认是右对齐的,如果希望改变方向,需要在占位符%后加 -
    printf("%-5sefg\n", str);// 输出为"abcd efg"
    return 0;
}

                3.2 总是显示正负号

        默认情况下使用printf 输出数字不会显示+号,只会显示-号 

        当我们在占位符%后加 +,输出的正数前会带+号,负数还是-号

int main()
{
    // 默认情况下使用printf 输出数字不会显示+号,只会显示-号。
    // 当我们在占位符%后加 +,输出的正数前会带+号,负数还是-号
    int num = 8;
    int num2 = -8;
    printf("%d\n", num); // 输出 8
    printf("%+d\n", num); // 输出 +8
    printf("%+d\n", num2); // 输出 -8
    return 0;
}

                3.3 限定小数位位数

                       

        在输出小数时,经常性的会有小数位数的要求,此时占位符的格式就可以写成 %.[N] lf 的形式来限定小数位数,N表示需要保留的小数位数                   

        在截取小数位数时默认会进行四舍五入,如果小数位不足时会在后面补0

int main()
{
    // 在输出小数时,经常性的会有小数位数的要求,此时占位符的格式就可以写成 %.[N] lf 的形式来限定小数位数,N表示需要保留的小数位数
    // 在截取小数位数时默认会进行四舍五入,如果小数位不足时会在后面补0
    double num3 = 3.1415926;
    printf("%.2lf\n", num3); // 输出 3.14
    printf("%.3lf\n", num3); // 输出 3.141
    printf("%.4lf\n", num3); // 输出 3.1416
    printf("%.12lf\n", num3); // 输出 3.141592600000
    return 0;
}

        当然限定小数位数与限定占位符最小宽度可以结合在一起使用

        可以用 * 代替,通过参数传入进来

int main()
{
    // 当然限定小数位数与限定占位符最小宽度可以结合在一起使用
    double num = 3.14;
    printf("%5.2lf\n", num); // 输出 " 3.14"

    // 可以用 * 代替,通过参数传入进来
    printf("%*.*lf\n", 5, 2, num);// 输出 " 3.14"
    return 0;
}

                3.4 限定字符串输出长度 

        %s占位符默认情况下会把所有字符全部输出。此时占位符的格式就可以写成 %.[N]s 的形式来限定输出的字符数量,N表示需要输出的字符数量 

int main()
{
    // %s占位符默认情况下会把所有字符全部输出。此时占位符的格式就可以写成 %.[N]s 的形式来限定输出的字符数量,N表示需要输出的字符数量
    char str2[] = "qwertyuiop";
    printf("%.1s\n", str2); // 输出 q
    printf("%.2s\n", str2); // 输出 qw
    printf("%.3s\n", str2); // 输出 qwe
    return 0;
}

 scanf 详解

        1. 基本用法

                Scanf函数用于读取用户在键盘上的输入,⽤⼾输⼊数据、按下回⻋键后, scanf 就会处理⽤⼾的输⼊,将其存⼊变量

                Scanf函数与printf的语法十分相识,利用占位符代替用户输入进来的值,格式字符串⾥⾯有多少个占位符,就有多少个值等待输入

         注意:变量前⾯必须加上 & 运算符(指针变量除外),因为 scanf() 传递的不是值,⽽是地址, 即将变量 i 的地址指向⽤⼾输⼊的值

        如果这⾥的变量是指针变量(⽐如字符串变量),那就不⽤加 & 运算符 

int main()
{
	int num = 0;
	int num2 = 0;
	int num3 = 0;
	// 从键盘中读取一个数放入进 num 中
	scanf("%d", num); // error  变量前面必须要加上 & ,scanf() 传递的不是值,⽽是地址
	scanf("%d", &num); // yes

	// 下⾯是⼀次将键盘输⼊读⼊多个变量
	scanf("%d %d %d", &num, &num2, &num3);
	return 0;
}

        scanf() 处理数值占位符时,会⾃动过滤空⽩字符,包括空格、制表符、换⾏符等

int main() 
{
	// Scanf()函数用于读取用户在键盘上的输入
	int num1 = 0;
	int num2 = 0;
	int num3 = 0;
	int num4 = 0;
	// scanf() 在处理占位符时,会自动过滤空白字符、空格、制表符、换行符等
	scanf("%d %d %d %d", &num1, &num2, &num3, &num4);
	// 用户输入
	// 输入方式一:1 2 3 4 
	
	// 输入方式二:
	// 1
	// 2
	// 3
	// 4

	// 输入方式三:
	// 1 2
	// 3 4
	// 以上输入方式都是等价的,一样的
	return 0;
}

         2. scanf的返回值

        scanf() 的返回值是⼀个整数,表⽰成功读取的变量个数,如果在成功读取任何数据之前,发⽣了读取错误或者遇到读取到⽂件结尾,则返回常量 EOF

int main()
{
	int num1 = 0;
	int num2 = 0;
	int num3 = 0;
	// scanf() 的返回值是⼀个整数,表⽰成功读取的变量个数
	int num = scanf("%d %d %d", &num1, &num2, &num3);
	printf("%d\n", num); // 输出 3
	return 0;
 }

 

                 当我们在一些算法竞赛或者日常练习中难免会出现以上类型的题目,题目只说明了有两个数将要被读入进来,却没有告诉我们有多少组这样的数,这个时候就可以用到我们scanf的返回值EOF来进行判断

int main()
{
	// 如果在成功读取任何数据之前,发⽣了读取错误或者遇到读取到⽂件结尾,则返回常量 EOF
	long long a = 0;
	long long b = 0;
	// 不管有多少组数据我都一直读取,直到发⽣了读取错误或者遇到读取到⽂件结尾,我就结束
	while (scanf("%ld %ld", &a, &b) != EOF)
	{
		printf("%ld\n", a + b);
	}
	return 0;
 }

        3. 占位符

                scanf() 常⽤的占位符与 printf() 的占位符基本⼀致,我就不过多介绍了,这里讲一下连个特殊的占位符(%c、%s)

                3.1 %c

        除了 %c 以外,都会⾃动忽略空⽩字符

int main()
{
	char ch1;
	char ch2;
	// 除了 %c 以外,都会⾃动忽略掉起首空⽩字符
	// 输入:" 12"
	scanf("%c %c", &ch1, &ch2);
	printf("-%c- -%c-\n", ch1, ch2);
	return 0;
}

        结果:

                如果要强制跳过字符前的空⽩字符,可以在% c 前加上⼀个空格,表⽰跳过零个或多个空⽩字符 

int main()
{
	char ch1;
	char ch2;
	// 如果要强制跳过字符前的空⽩字符,可以在% c 前加上⼀个空格,表⽰跳过零个或多个空⽩字符
	scanf(" %c %c", &ch1, &ch2);
	printf("-%c- -%c-\n", ch1, ch2);
	return 0;
}

                 3.2 %s

        它的规则是,从当前第⼀个⾮空⽩字符开始读起,直到遇到空⽩字符(即空格、换⾏符、制表符等)就停止读取

                        那么这就会导致一个问题出现,假如我们像读取一句英文或者句子时就会导致不能够完全读取

int main()
{	
	char str[100] = "";
	// 它的规则是,从当前第⼀个⾮空⽩字符开始读起,直到遇到空⽩字符(即空格、换⾏符、制表符等)就停止读取
	// 输入:"are you ok"
	scanf("%s", str);
	printf("%s\n", str); // 输出 are
	return 0;
}

 

        gets()函数 会读取整行输入行,直至遇到换行符,然后丢弃换行符,储存其余字符,并在字符末尾添加一个空字符使其成为C字符串(头文件 <stdio.h>)

int main()
{	
	char str[100] = "";
	// 它的规则是,从当前第⼀个⾮空⽩字符开始读起,直到遇到空⽩字符(即空格、换⾏符、制表符等)就停止读取
	// 输入:"are you ok"
	// gets()函数 会读取整行输入行,直至遇到换行符
	gets(str);
	printf("%s\n", str); // 输出 are you ok
	return 0;
}

        scanf() 将字符串读⼊字符数组时,不会检测字符串是否超过了数组⻓度 

                由于这个因素就会导致scanf这个函数十分的不安全,如果输入的字符串的长度超过了字符数组的长度,就会导致预想不到的结果 

int main() 
{
	// scanf() 将字符串读⼊字符数组时,不会检测字符串是否超过了数组⻓度
	char str[5] = "";
	// 输入:"123456789"
	scanf("%s", str);
	return 0;
}

 

         4. 赋值忽略符

        有时输⼊可能不符合预定的格式,避免这种情况, scanf() 提供了⼀个赋值忽略符( *),只要把 * 加在任何占位符的百分号后⾯,该占位符就不会返回值,解析后将被丢弃 

int main()
{
	int year = 0;
	int month = 0;
	int day = 0;
	// 有时输⼊可能不符合预定的格式
	// 比如:1/1/1	1--1--1--
	scanf("%d-%d-%d", &year, &month, &day);
	// 就会导致输出的数可能不是我们想要的
	printf("%d %d %d\n", year, month, day);

	// 把 * 加在任何占位符的百分号后⾯,该占位符就不会返回值,解析后将被丢弃
	// 此时不论时 1/1/1,1--1--1还是什么都可以精准读取
	scanf("%d%*c%d%*c%d", &year, &month, &day);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值