首页 / 资讯中心 / 文章详情

C语言:printf 与 scanf 详解:占位符、输出格式、返回值与赋值忽略符

C语言:printf 与 scanf 详解:占位符、输出格式、返回值与赋值忽略符 ★ FEATURED ARTICLE
【C语言学习笔记】printf 与 scanf 详解占位符、输出格式、返回值与赋值忽略符学习主题《从 C 语言到 AI 编程实践》本篇知识点printf 基本用法与不自动换行、占位符与参数个数对应、宽度 / 对齐 / 正负号 / 小数位 / 部分字符串、scanf 的读取原理与返回值、%c 与 %s 的空白处理、%s 越界、赋值忽略符一、printf 基本用法printf print f其中的f代表 format格式化表示可以定制输出文本的格式。它把参数文本输出到屏幕。#includestdio.hintmain(){printf(Hello World);return0;}输出Hello World。连写两个printf(Hello World);printf(hehe);// 输出Hello Worldheheprintf 不会在行尾自动换行运行结束后光标停在输出结束的位置不自动换行。想让光标到下一行开头要显式加\n。printf(Hello World\n);printf(hehe);// 输出两行如果漏掉#include stdio.hwarning C4013: printf 未定义假设外部返回 int error LNK2019: 无法解析的外部符号 printf函数 main 中引用了该符号 fatal error LNK1120: 1 个无法解析的外部命令这说明printf是库函数必须包含stdio.h头文件。二、占位符与参数个数占位符就是这个位置可以用其他值代入。printf(There are 3 apples\n);printf(There are %d apples\n,5);// There are 5 applesprintf(%s will come tonight\n,lisi);// lisi will come tonight参数与占位符是一一对应的有 n 个占位符printf的参数就应该有 n 1 个格式串本身算一个。个数不匹配时会输出内存中的任意值printf(%s says it is %d oclock\n,wangwu);// 少给了一个参数打印出内存中的随机值// wangwu says it is -4 oclock打印地址用%pinta10;printf(a的地址是: %p\n,a);// 类似 0000005B81AFBF42.1 常用占位符占位符对应类型%cchar%dint / signed int十进制%uunsigned int十进制%hd/%hushort / unsigned short%ld/%lulong / unsigned long%lld/%llulong long / unsigned long long%ffloatdouble 也可用%f也可用%lf%Lflong double%p指针打印地址%s字符串%x十六进制整数%zusize_t三、输出格式3.1 限定宽度与对齐printf(%d\n,123);//123printf(%5d\n,123);// 123 宽度至少 5 位不足补空格printf(%5d\n,123456);//123456 超过 5 位就按实际位数输出默认右对齐前面补空格在%后加-变成左对齐printf(----%5d----\n,123);//---- 123----printf(----%-5d----\n,123);//----123 ----浮点同理printf(%f\n,123.45);//123.450000 默认 6 位小数printf(%12f\n,123.45);// 123.450000printf(%-12f\n,123.45);//123.450000 3.2 总是显示正负号默认只给负数显示-加后正数也带正号printf(%d\n,12);//12printf(%d\n,12);//12printf(%d\n,-12);//-123.3 限定小数位数printf(%f\n,123.456);//123.456000printf(%.2f\n,123.456);//123.46printf(%6.2f\n,0.5);// 0.50 宽度 6保留 2 位宽度和小数位数都可以用*代替由参数传入intm6,n2;printf(%*.*f\n,m,n,0.5);// 0.503.4 输出部分字符串%.[m]s指定输出长度printf(%s\n,abcdefghi);//abcdefghiprintf(%.5s\n,abcdefghi);//abcde四、scanf 基本用法scanf读取键盘输入原型在stdio.h。程序运行到它时会停下等用户输入并回车然后把输入存入变量。intmain(){intscore0;printf(请输入成绩:);scanf(%d,score);printf(成绩是%d\n,score);return0;}// 请输入成绩:88// 成绩是88数据流键盘 →标准输入 stdin→ 程序变量 →标准输出 stdout→ 屏幕。一次读多个值inti0,j0;floatx0.0,y0.0;scanf(%d%d%f%f,i,j,x,y);// 输入 1 -20 3.4 -4.0e3输入多个值时数据之间用一个或多个空格、甚至换行分开都不影响——scanf处理数值占位符时会自动过滤空白字符空格、制表符、换行符。五、scanf 的读取原理用户的输入先放进缓存按下回车后才按占位符对缓存进行解读。解读时从上一次解读遗留的第一个字符开始直到读完缓存或者遇到第一个不符合条件的字符为止。intx;floaty;// 用户输入 -13.45e12# 0scanf(%d,x);// 跳过空格读 -13遇到 . 停止. 不是整数的合法字符printf(%d\n,x);// -13scanf(%f,y);// 从上次停下的 .45e12# 0 继续printf(%f\n,y);// 449999994880.000000理解从上一次遗留处继续这一点后面很多输入问题就解释得通了。六、scanf 的返回值scanf的返回值是成功读取的变量个数一个都没读到返回 0在读任何数据之前遇到错误或文件结尾返回常量EOF-1。inta0,b0;floatf0.0f;intrscanf(%d %d %f,a,b,f);printf(a%d b%d f%f\n,a,b,f);printf(r %d\n,r);输入结果说明10 20 4.5a10 b20 f4.500000r3三个都读到10 20 abca10 b20 f0.000000r2第三个不是数字10 #a10 b0 f0.000000r1第二个不匹配#a0 b0 f0.000000r0一个都没读到CtrlZ全 0r-1遇到文件结尾返回 EOF竞赛里的多组数据输入就靠返回值inta0,b0;// 只写一次 scanf输入多组时只会读第一组// scanf(%d %d, a, b);while(scanf(%d %d,a,b)2)// 读满两个才继续{printf(%d\n,ab);}也可以写成while (scanf(%d %d, a, b) ! EOF)。七、scanf 的占位符占位符说明%c字符%d整数%ffloat%lfdouble%Lflong double%s字符串%[]指定匹配的字符集遇到不在集合中的字符就停止printf 与 scanf 的%f差异printffloat用%fdouble用%f或%lf都行scanffloat用%fdouble必须用%lf。7.1 %c 不跳过空白除%c外所有占位符都会自动忽略起首的空白字符。%c总是取当前第一个字符哪怕它是空格。charn0;scanf(%c,n);// 输入 abc输出 读到的是空格本身scanf( %c,n);// 输入 abc输出 a格式串里的空格表示跳过空白要跳过空白就在%c前加一个空格。7.2 %s 与 %[]%s遇到空白字符空格、制表符、换行就停止chararr[20];scanf(%s,arr);// 输入 abc def只得到 abcprintf(%s\n,arr);// 注意数组名本身就是地址这里不用 想读带空格的字符串用字符集scanf(%[a-z],arr);// 输入 abcdefg1234 → abcdefg遇到不在 a-z 的字符停止scanf(%[^\n],arr);// 输入 abc def → abc def读到除换行外的所有字符八、%s 的越界与赋值忽略符8.1 %s 不检查长度%s读入字符数组时不检测是否超过数组长度很容易写越界chararr[5];scanf(%s,arr);// 输入 abcdefgh9 字节→ 栈被破坏// Run-Time Check Failure #2 - Stack around the variable arr was corrupted.正确做法是指定最大长度%[m]s。数组 5 个字节最多读 4 个留 1 个给\0chararr[5];// [][][][][\0]scanf(%4s,arr);// 输入 abcdefgh → abcd同样的坑还有类型不匹配inta0;floatf0.0;scanf(%d,a,f);// 少写了一个占位符// C4477 scanf: 格式字符串 %d 需要类型 int * 的参数// 但可变参数 1 拥有了类型 float *运行时会破坏栈占位符必须与变量类型、个数严格对应。8.2 赋值忽略符 %*c输入格式不固定时比如分隔符可能是-也可能是/intyear0,month0,day0;scanf(%d-%d-%d,year,month,day);// 输入 10-20-30 → 10 20 30正确// 输入 10/20/30 → 10 0 0分隔符不匹配后面全部失败两种修法。第一种用%c把分隔符吃进变量charc10,c20;scanf(%d%c%d%c%d,year,c1,month,c2,day);更简洁的是赋值忽略符*加在任何占位符的百分号后面该占位符照样解析但结果被丢弃。scanf(%d%*c%d%*c%d,year,month,day);// 输入 10-20-30 或 10/20/30都输出 10 20 30%*c就是读一个字符但不要它无论分隔符是什么都能跳过。九、本篇踩坑清单#坑现象正确做法1以为 printf 会自动换行两次输出粘在一起结尾加\n2漏写#include stdio.hC4013、LNK2019用库函数就包含头文件3占位符比参数多打印内存随机值如 -4占位符与参数一一对应4以为 scanf 能读完一整行只读到第一个空格用%[^\n]或fgets5%c前不加空格读到前导空格写 %c6double用%f输入结果错乱scanf 里必须用%lf7%s不限长度Run-Time Check Failure #2栈被破坏写%4s留一位给\08scanf 占位符与变量类型不符C4477运行时破坏栈类型、个数严格对应9用scanf(%d-%d-%d)固定分隔符输入用/就失败用%*c吃掉分隔符10多组输入只写一次 scanf只处理第一组while (scanf(...) 2)十、小结printf不自动换行占位符个数 参数个数 − 1少给参数会打印内存随机值输出格式可以组合宽度%5d、左对齐%-5d、正负号%d、小数位%.2f、部分字符串%.5s宽度和精度还能用*从参数传入scanf按缓存解读、从上次遗留处继续返回值是成功读取的个数多组输入靠它判断%c不跳空白、%s遇空白即停且不检查长度——前者要加空格后者要写%4s这类上限分隔符不确定时用%*c忽略。标签C语言printfscanf占位符输入输出学习笔记
阅读完成 · 觉得有帮助?
咨询建站