C语言|printf()和scanf()详解

1.字符和字符串

1.1 字符型常量

字符型常量的形式如下

  1. 用单引号括起来的一个字符,如’a’、‘2’
  2. 合法的转义字符,可见另一篇文章
    转义字符详解

1.2 字符串

字符串是一个或者多个字符的序列,如"Hello world!",但需要注意的是双引号不是字符串的一部分,双引号仅告知编译器它括起来的是字符串

在C语言中,没用专门用来存储字符串的变量类型,即没有原生的String类型,字符串都被存储在char类型的数组中,数组由连续的存储单元组成,而字符串中的字符被存储在相邻的存储单元中,其中每个单元存储一个字符,并且以空字符 \0来结束 ,如图
字符串比较

因此在C语言中字符长度和存储它的单元大小有所不同

#include <stdio.h>  
#include <string.h>  
  
#define length "Hello world"  
int main() {  
char Demo1[] ="Hello world!";  
printf("strlen为%zd\n",strlen(Demo1));  
printf("sizeof为%zd\n",sizeof(Demo1));  
return 0;  
}

运行结果
运行结果

2. printf()函数

printf()是C库的输出函数,用于格式化后的字符串输出,使用时需申明头文件stdio.h
在请求printf()函数打印数据的指令要与待打印数据类型相匹配,即需要使用相对应的转换说明

2.1 格式

printf(格式字符串,待打印项1,待打印项2,……)
格式化字符串的构成:实际要打印的字符和转换说明
如`printf(“参数二为%d.\n”,a);

2.2 转换说明的构成

构成

简单来说分为两点

  1. 转换说明
  2. 修饰符,而修饰符又可以进行细分,如图
    修饰符

2.2.1 转换说明

转换说明输出
%a浮点数、十六进制数和p记数法
%A浮点数、十六进制数和p记数法
%c单个字符
%d有符号十进制整数
%e浮点数、e记数法
%E浮点数、e记数法
%f浮点数、十进制记数法
%g根据值的不同,自动选择%f或%e
%G根据值的不同,自动选择%f或%e
%i有符号的十进制整数(和%d相同)
%p指针
%s字符串
%o无符号八进制整数
%u无符号十进制整数
%x无符号十六进制整数,使用十六进制数0f
%X无符号十六进制整数,使用十六进制数0F
% %打印一个百分号

2.2.2 标记

标记含义
待打印项左对齐。即从字段的左侧开始打印该项
*可代替字段宽度,放在%和转换说明符之间
+有符号值若为正,则在值在前面显示加号;若为负,则在值前面显示减号
空格有符号值若为正,则在值前面显示前导空格(不显示任何符号);若为负,则在值前面显示减号,但+标记会覆盖空格
#把结果转换为另一种形式。如果是%o格式,则是以0开始;如果是%x或%X格式,则以0x或者0X开始;对于所有的浮点格式,#保证了即使后面没有任何数字,也打印一个小数点字符。对于%g和%G格式,#防止结果后面的0被删除
0对于数值格式,用前导0代替空格填充字段宽度。对于整数格式,如果出现-标记或者指定精度,则忽略该标记
#include <stdio.h>  
  //这里为了直观看清区别,我将字段宽度规定为10
int main() {  
int a = 121;  
int b =10
printf("[%-10d]\n",a);//标记为 -
printf("[%+10d]\n",a);//标记为 +
printf("[%+10d]\n",-a);//标记为 +,测试值为负的情况  
printf("[% 10d]\n",a);//标记为空格  
printf("[%#10o]\n",a);//标记为 #的%o格式  
printf("[%#10X]\n",a);//标记为 #的%X格式  
printf("[%010d]\n",a);//标记为 0
printf("[%*d]\n",b,a);//标记为 *
return 0;  
}
//运行结果
[121       ]
[      +121]
[      -121]
[       121]
[      0171]
[      0X79]
[0000000121]
[       121]

2.2.3 数字和精度

修饰符含义
数字输出时的最小字段宽度,但如果该字段不能容纳待打印的数字和字符串,系统则会使用更宽的字段
.数字精度的要求
对于%e、%E和%f转换,表示小数点右边数字的位数
对于%g和%G转换,表示有效数字的最大位数
对于%s转换,表示待打印字符的最大数量
对于整型转换,表示待打印数字的最小位数
如有必要,使用前导0来达到这个位数
只使用.表示其后跟随一个0,所以%.f和%.0f相同
#include <stdio.h>  
  
int main() {  
double a = 121.33;  
char b[] = "hello";  
int c = 0324;  
printf("[%f]\n",a);  
printf("[%.3e]\n",a);  
printf("[%10.3g]\n",a);  
printf("[%10.6g]\n",a);  
printf("[%10.3s]\n",b);  
printf("[%.6d]\n",c);  
printf("[%10.6d]\n",c);  
return 0;  
}

//运行结果
[121.330000]
[1.213e+002]
[       121]
[    121.33]
[       hel]
[000324]
[    000324]

2.2.4 类型表示的修饰符

修饰符含义
h和整型转换说明一起使用,表示short或unsigned short类型的值
hh和整型转换说明一起使用,表示char或unsigned char类型的值
l和整型转换说明一起使用,表示long或unsigned long类型的值
ll和整型转换说明一起使用,表示long long或者unsigned long long类型的值
L和浮点转换说明一起使用,表示long double类型的值
z和整型转换说明一起使用,表示size_t类型的值,size_t是sizeof返回的类型

3. scanf()

printf()是C库的输入函数,用于格式化后的字符串输入,使用时需申明头文件stdio.h
在请求scanf()函数打印数据的指令要与待打印数据类型相匹配,即需要使用相对应的转换说明

3.1 格式

scanf(格式化字符串,参数列表)

  • 格式化字符串表明字符输出流的目标数据类型。
  • 参数列表中使用指向变量的指针,其中两条规则
    1.如果用scanf()读取基本变量类型的值,在变量名前需加一个&
    2.如果用scanf()把字符串读入字符数组中,不用使用&

3.2 转换说明

image.png

其中修饰符又可以进行细分
1. *
2. 数字
3. 类型表示

3.2.1 转换说明

修饰符含义
%c把输入解释为字符
%d把输入解释为有符号十进制整数
%i把输入解释为有符号十进制整数
%o把输入解释为有符号八进制整数
%p把输入解释为指针
%s把输入解释为字符串,从第一个非空白字符开始,到下一个空白字符之前的所有字符都是输入
%u把输入解释为无符号十进制整数
%e、%f、%g、%a把输入解释为浮点数
%E、%F、%E、%A把输入解释为浮点数
%x、%X把输入解释为有符号十六进制整数

空白字符:. :1.空格(‘ ’)
2.换页(‘\f’)
3.换行(‘\n’)
4.回车(‘\r’)
5.水平制表符(‘\t’)
6.垂直制表符(‘\v’)

3.2.1.1 细节
  • scanf()中可以把普通字符放在格式化字符串中,但除了空格字符外,在输入时必须严格匹配,如scanf("%d,%d",&a,&b);这里输入时必须输入12,13 ,不能缺少逗号.但如果是scanf("%d %d",&a,&b);在输入时,需要至少一个空格作为间隔,如12 1312 13输入时效果一样
  • 一般,scanf()函数每次读取一个字符,跳过所有的空白字符,直到遇到第一个非空白字符才开始读取
  • 在%d中,如果第一个非空白字符为非数字字符,scanf()会停止读取,并把A放回输入中,不会把值赋给指定变量,而程序在下一次读取输入时,首先读取的字符是A,但如果只使用%d转换说明,scanf()则会无法跨越A读取下一个字符
  • 对于%c中,会从第一个字符开始读取,而不再是第一个非空白字符。如果需要从第一个非空白字符读取,则需要格式字符串前加一个空格,如scanf(" %c",&a)

3.2.2 转换说明的修饰符

修饰符含义
*抑制赋值
数字最大字符宽度。输入达到最大字段宽度处,或第1次遇到空白字符时停止
hh把整数作为signed char或者unsigned char类型读取
ll把整数作为long long或unsigned long long类型读取
h、l和L%hd和%hi表明把对应的值存储为short类型;
%ho、%hx和%hu表明把对应的值存储为unsigned short类型
%ld和%li表明把对应的值存储为long类型
%lo、lx和%lu表明把对应的值存储为unsigned long类型
%le、%lf和%lg表明把对应的值存储为double类型
在e、f和g前面使用L而不是l,表明把对应的值被存储为long double类型
z在整型转换说明后面时,表明使用sizeof的返回类型

对于* 有抑制赋值的作用,即会使scanf()跳过相应的输入项

#include <stdio.h>  
  
int main() {  
int a;  
scanf("%*d %*d %d",&a);  
printf("a为%d",a);  
return 0;  
}

这里我输入`3 24 324
运行结果为

a为324
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Aweken dream

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值