C语言细节 字符串与格式化输入输出

1.printf()何时发送内容到屏幕:

printf()会先把要输出的内容发送到1个叫缓冲区(Buffer)的中间存储区域,然后缓冲区中的内容再不断被发送到屏幕上
从缓冲区把数据发送到屏幕或文件称为刷新缓冲区,C标准规定:当缓冲区被填满,遇到'\n'或需要输入时刷新缓冲区
旧式编译器遇到scanf()也不会强行刷新缓冲区,程序会停在那里不显示任何提示内容,等待用户输入数据
在这种情况下,可以使用'\n'来刷新缓冲区,但这会导致光标移动到下1行起始位置;还可以用fflush()刷新缓冲区

2.空字符(Null Character):

C语言使用字符数组来存储字符串,字符串必须以'\0'结尾(会自动补上)
'\0'是空字符,是非输出控制符,其ASCII码是0
由于必须以'\0'结尾,字符数组的长度必须至少比要存储的字符串的长度多1
比如有10个字符的字符串必须存储在长度至少为11的字符数组中

在这里插入图片描述
3.标准化输入输出函数的标准:

scanf()printf()被称为标准化输入/输出函数,或简称I/O函数
最初,C把输入/输出的实行留给了编译器的作者,所以不同编译器提供的I/O函数可能有区别
不过,C90/C99规定了I/O函数的标准版本

4.转换说明修饰符:

输出控制符被称为转换说明(Conversion Specification),其中%后面的符号称为转换字符
通过在%和转换字符间插入转换说明修饰符来修饰基本的转换说明

//注意:
1.所有下述修饰符都是C99新增的
2.如果要插入多个修饰符,插入顺序应和下面列出的顺序相同

①标记
  -:将待打印项左对齐,即从字段的左侧开始打印该项."%-20s"
    //默认是最右侧,左侧用前导空格填充
  +:显示值的符号(如果有)."%+6.2f"
  空格:有符号项若为正,则在前面显示前导空格(不显示符号);若为负,则显示负号并覆盖空格."% 6.2f"
  #:把结果转换为另1种形式
    如果是%o格式,则以0开始
    如果是%x/%X格式,则以0x/0X开始
    对于所有浮点格式,保证了即使后面没有任何数字,也打印1个小数点字符
    对于%g/%G格式,防止结果结尾的0被删除
    如"%#o","%#8.0f","%+#10.3e","%#%g"
  0:对于数值格式.用前导0代替空格填充字段宽度
    对于整数格式,如果出现负号标记或指定了精度,则忽略负号
    如"%010d","%08.3f"
②数字:指定最小字段宽度."%4d".数字:指定精度
  对于%e/%E/%f格式,表示小数点后的位数
  对于%g/%G格式,表示有效数字最大位数
  对于%s格式,表示待打印字符的最大数量
  对于整数格式,表示待打印数字的最小位数
  如有必要,使用前导0来达到这个位数
  只使用.相当于.0"%5.2f","%.f"(相当于"%.0f")
//指定字段宽度的一些用法:
float distance=10.22;
printf("Count Beppo ran %.2f miles in 3 hours.\n",distance);
//结果:Count Beppo ran 10.22 miles in 3 hours.
//指定比字段宽度更小的宽度,以防止出现多余的空格
printf("Count Beppo ran %10.2f miles in 3 hours.\n",distance);
//结果:Count Beppo ran      10.22 miles in 3 hours.

5.size_t与ptrdiff_t类型:

标准只规定了sizeof()的返回值应该是无符号整数,在不同的实现中,可以是unsigned/unsigned long/unsigned long long
如果要打印sizeof()的返回值,根据环境,需要使用%u/%lu/%llu,这意味着移植程序时需要进行修改,为此,C提供了更好的类型
stddef.h把size_t定义成sizeof()返回的类型,称为底层类型(Underlying Type),printf()使用z修怖符表示打印相应类型
同样,C还定义了ptrdiff_t类型和t修饰符来表示系统使用的指针差值的底层有符号整数类型

6.输出时类型不匹配的补充:

//混淆整型/字符类型:

short a=336;
printf("%c\n",a);//结果:P
//超出255时,%c只会查看最后1个字节,并将该字节翻译为字符并显示(见下图)
//即该值被解释成"以256为模"(modulo 256),相当于除以256后取余数,再把余数翻译成字符

short num=336,mnum=-336;
printf("%hd,%hu,%hd,%hu\n",num,num,mnum,mnum);//结果:336,336,-336,65200
//336的补码表示为336;而-336的补码表示为65200,作为unsigned short时被解释为65200

int big=65618;
printf("%d,%hd\n",big,big);//结果:65618,82
//这时也进行了求模运算,只查看最后2B

在这里插入图片描述

//混淆整型与浮点型:

float n1=3.0;
double n2=3.0;
long n3=2000000000,n4=1234567890;
printf("%.1e,%.1e,%.1e,%.1e\n",n1,n2,n3,n4);//结果:3.0e+000,3.0e+000,9.9e-315,-1.$e+000
//%e让printf()认为n3是double,因此除了查看n3的4B,还需要查看相邻的4B
//让后将这8B分别解释为小数部分和指数部分
315,-1.$e+000
printf("%ld,%ld,%ld,%ld\n",n1,n2,n3,n4);//结果:0,0,2000000000,1234567890
//不能用%ld输出浮点型
//注意:再某些环境下,这种情况下n3/n4也会输出错误

7.printf()输出长字符串:

//方法1:使用多个printf(),除最后1个外,不要加'\n'
printf("My name is John Smith,");
printf("I am 10 years old.\n");
//结果:My name is John Smith,I am 10 years old.

//方法2:使用字符串连接
  //多个str间如果用空白隔开,会被视为1个str
printf("Here is another way"
"to print "   "a long str.\n");
//结果:Here is another wayto print a long str.

//方法3:使用反斜杠(\)来断行
  //下1行必须从该行的最左侧开始,如果缩进,缩进所产生的空白也会被视为字符串的一部分
int main(void) {
	printf("Third way to \
print a long str.\n");
	return 0;
}
//结果:Third way to print a long str.

8.*修饰符:

//printf()的*修饰符:
如果不想预先指定字段宽度,而想通过变量指定,使用*修饰符
int a=5;
printf("%*d\n",a,a);//结果:    5

//scanf()的*修饰符:
会跳过使用*修饰符的输入项,将下1个输入项赋给变量
  //需要读取文件的特定列时很有用
int a;
scanf("%*d,%d",&a);//输入:3,2
printf("%d\n",a);//结果:2

9.输入数组元素:

int index,score[3];
for (index=0;index<3;index++) {
    printf("input score:");
    scanf("%d",&score[index]);
}
printf("output all score:");
for (index=0;index<3;index++) {
    printf("%d,",score[index]);
}
//结果①:
//input score:9
//input score:2
//input score:4
//output all score:9,2,4,
//结果②:
//input score:5 2 9
//input score:input score:output all score:5,2,9,
//结果③:
//input score:4 7 9 3 2
//input score:input score:output all score:4,7,9,
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值