当前位置: 首页 > news >正文

scanf、printf使用详解

scanf

函数原型

#include <stdio.h>

int scanf(const char *format, ...);

参数:

  • format:字符串参数,包含三种类型

    • 空白字符:它们与输入的零个或多个空白字符匹配,在处理中常被忽略

      • int num1 = 0;
        int num2 = 0;
        
        scanf("%d       %d", &num1, &num2);
        
        // 此时scanf中有7个空白字符(空白字符不仅仅是空格,还可以是制表符、回车符)
        // 但在实际输入中输入1个或多个空白字符都是可以正确读取的
        // 至少要有一个空白字符是要分开两个数字,否则会被当成一个数字
        
    • 格式代码:它们指定函数如何解释接下来的输入字符

      • // 同样的二进制数,不同的解释就会有不同的结果
        // 八位二进制数:1000 0001 
        // 有符号数: -1
        // 无符号数: 129
        
        printf("%d\n", -1);
        printf("%u\n", -1);
        
    • 其他字符:当其他字符出现在格式字符串时,下一个输入字符必须与它匹配

      • 如果匹配,该输入字符随后被丢弃

      • 如果不匹配,函数就不再读取而是直接返回

      • int num1 = 0;
        int num2 = 0;
        
        scanf("请输入第一个数字:%d,请输入第二个数字:%d", &num1, &num2);
        
        // 如果在终端输入形式如下: 12 31
        // 那么此时scanf会直接返回,并不会将两个数字读取到num1、num2
        // 正确的输入形式应是: 请输入第一个数字:12,请输入第二个数字:31
        // 这样scanf才能正确的读取
        
  • ...:表示一个可变长度的指针列表

    • 从输入转化而来的值逐个存储到这些指针参数所指向的内存
      • 由此可见,scanf参数前面为什么要加&符号就比较清楚了
      • 如果没加&符号,将变量的值传递给函数,而scanf函数却把它解释为一个指针
        • 当它被解引用将数据写入时,要么导致程序终止,要么导致一个不可预料的内存位置的数据被改写

返回值:

当格式化字符串到达末尾或者读取的输入不再匹配格式字符所指定的类型时,输入就停止。

  • 被转化的输入的数目作为函数的返回值
  • 如果在任何输入值被转换之前文件就已经到达末尾,函数就返回常量值EOF
    • EOF是常量值-1,与ASCII中字符都不相同,这是为了避免二进制被错误解释为EOF

scanf的格式控制

格式字符串的形式为:

%[可读取的最大宽度][限定符]类型

%[width][modifiers]type

width

width(宽度,可选)是一个数值,用于指定当前读取操作中读取的最大字符数。

int num = 0;

scanf("%3d", &num);

// 如果在终端输入1002,num最多只能读取三个字符,所以num的值为100

modifiers

格式代码hlL
d、i、nshortlong
o、u、xunsigned shortunsigned long
e、f、gdoublelong double

限定符的主要目的是为了指定参数的长度。如果整形参数比缺省的整形参数更短或更长,在格式代码中省略限定符就是一个常见的错误。浮点类型也是如此。

如果省略了限定符,可能会导致一个较长变量只有一部分被初始化,或者一个较短变量的相邻内存也被修改。

double dNum = 0.0;
long double ldNum = 0.0;
// 如果只使用%f,那么就会导致有一部分没被初始化
scanf("%lf", &dNum);
scanf("%Lf", &ldNum);

short int sNum = 0;
// 如果只使用%d,那么就会导致相邻内存被非法修改,这极有可能导致进程崩溃
scanf("%hd", &sNum);

各种数据类型占用空间大小

数据类型占用内存(32位)占用内存(64位)
char11
unsigned char11
short22
unsigned short22
int44
unsigned int44
long48
unsigned long48
float44
double88

type

type(转换字符,必选)的内容及含义如下:

转换字符参数类型含义
cchar*读取单个字符。如果给出宽度,就读取这个数目的字符
iint*根据前缀决定基数,可以是八进制(前缀0)、十进制、十六进制(前缀0x)有符号整数
dint*十进制有符号整数
u、o、xunsigned int*无符号整数。u被解释为十进制、o被解释为八进制、x被解释为十六进制
f、e、E、g、Gfloat*浮点型字面值常量。但小数点不是必须的,也可以使用指数形式(大小写没有区别)
schar*读取一串非空字符串
pvoid*读取一个指针(即内存地址)
nint*到目前为止通过调用scanf函数从输入读取的字符数被返回,%n转换的字符并不在计算scanf函数的返回值之内,它本身不消耗任何输出
%(无)两个%%就是%本身,与输入的%相匹配
int num = 0;
int num1 = 0;
int num2 = 0;

scanf("%d %d%n", &num1, &num2, &num);
printf("%d\n", num);

// 若在终端输入10   02
// 那么num的值为7,因为中间输入的三个空格也是scanf读取到的字符

printf

函数原型

#include <stdio.h>

int printf(const char *format, ...);

参数:

  • format:字符串参数,包含二种类型
    • 格式代码:指定转换的执行方式
    • 其他字符:原样逐字打印
  • ...:用于转换的参数列表

返回值:

如果函数调用成功,返回值是实际打印的字符数(不包含表示字符串结束的 ‘\0’);

如果函数调用失败,返回值是一个负数。

printf的格式控制

格式字符串的形式为:

%[标志][输出最小宽度][.精度][修改符]类型

%[flags][width][.precision][modifiers]type

flags

flags可同时出现多个,且无顺序要求。

标志含义
-指定被转换的参数在其字段内左对齐(默认是右对齐)
+指定在输出的数前面加上正负号
空格如果第一个字符不是正负号,则在其前面加上一个空
0对于数值转换,当输出长度小于字段宽度时,添加前导0进行填充
#指定下表的另一种输出形式
用于#标志
o保证产生的值以一个零开头
x、X在非零值前加0x前缀(%X则为0X)
e、E、f确保结果始终包含一个小数点,即使后面没有数字
g、G确保结果始终包含一个小数点,即使后面没有数字。另外,后缀的0并不会从小数中去除

width

width(宽度,可选)是一个数值,用于指定要输出的最小字符数。

转换后的参数输出宽度至少要达到这个数值。如果参数的字符数小于该数值,则在参数左边填充字符(默认是空格)。

  • 如果flags设置为-,要求参数左对齐的话则在右边填充

.precision

.precision(.精度,可选),通过点号分隔字段的宽度和精度。

  • 对于字符串,它指定打印的字符的最大个数
  • 对于整数,它指定打印的数字的最小位数
    • 必要时可填充0以达到位数要求
  • 对于转换字符为 e、E 或 f,它指定小数点后打印的数字位数
    • 会发生进位
    • 必要时可填充0以达到位数要求
  • 对于转换字符为 g 或 G,它指定打印的有效数字位数
    • 会发生进位

modifiers

  • hh表示将相应的参数按signed char/unsigned char类型输出
  • h表示将相应的参数按short/unsigned short类型输出
  • l表示将相应的参数按long/unsigned long类型输出
  • ll表示将相应的参数按long long/unsigned long long类型输出
  • L表示将相应的参数按long double类型输出
    • 仅适用于浮点数说明符,上面仅适用于整数说明符

type

type(转换字符,必选)的内容及含义如下:

转换字符参数类型含义
cint参数被裁剪为unsigned char类型并作为字符打印
d、iint参数作为有符号十进制整数打印
u、o、x、Xunsigned int参数作为无符号值打印。u使用十进制;o使用八进制;x或X使用十六进制(两者的区别是:x使用小写字母,X使用大写字母)
e、Edouble参数以指数形式输出单、双精度浮点数。小数点后面的位数由精度字段决定,默认是6(两者的区别是:打印时e的大小写)
fdouble参数按照常规的浮点数形式打印。小数点后面的位数由精度字段决定,默认是6
g、Gdouble参数以%f或%e中较短的输出宽度输出单、双精度浮点数
schar*打印一个字符串
nint*不产生任何输出,到目前为止函数所产生的输出字符数目将被保存到对应的参数中
%(无)打印一个%字符

注:如果 % 后边的字符不是转换字符,则其行为没有定义。

相关文章:

  • 基于文化算法优化的神经网络预测研究(Matlab代码实现)
  • ubuntu安装mysql详细过程
  • SpringCloud面试题及答案 300道,springcloud面试题总结 (持续更新)
  • 图文详解核方法——以核支持向量机KVSM为例
  • 计算机视觉 Project 1:Image Filtering and Hybrid Images
  • 云计算-Linux文件类型介绍,归属关系,基本权限介绍
  • DVWA靶场环境搭建
  • ES核心概念、IK分词器
  • 【JAVA】总结Java线程的几种状态
  • day009--mysql中的日期函数
  • sql语句 如果为空值显示为0
  • 【MySQL数据库】- 多表查询
  • C++文件服务器项目—数据库表设计 与 后端接口设计—6
  • 聊聊Redis的数据热点问题
  • 猿创征文|瑞吉外卖——管理端_员工管理
  • 11111111
  • 2017前端实习生面试总结
  • 4月23日世界读书日 网络营销论坛推荐《正在爆发的营销革命》
  • Angular 2 DI - IoC DI - 1
  • angular2开源库收集
  • DataBase in Android
  • docker-consul
  • echarts花样作死的坑
  • Invalidate和postInvalidate的区别
  • Java面向对象及其三大特征
  • markdown编辑器简评
  • Netty+SpringBoot+FastDFS+Html5实现聊天App(六)
  • Next.js之基础概念(二)
  • VirtualBox 安装过程中出现 Running VMs found 错误的解决过程
  • Vue.js-Day01
  • 笨办法学C 练习34:动态数组
  • 关于Java中分层中遇到的一些问题
  • 开发了一款写作软件(OSX,Windows),附带Electron开发指南
  • 区块链技术特点之去中心化特性
  • 让你的分享飞起来——极光推出社会化分享组件
  • 线上 python http server profile 实践
  • 源码之下无秘密 ── 做最好的 Netty 源码分析教程
  • 东超科技获得千万级Pre-A轮融资,投资方为中科创星 ...
  • (2009.11版)《网络管理员考试 考前冲刺预测卷及考点解析》复习重点
  • (翻译)Quartz官方教程——第一课:Quartz入门
  • (附源码)spring boot建达集团公司平台 毕业设计 141538
  • (简单) HDU 2612 Find a way,BFS。
  • (免费领源码)python#django#mysql公交线路查询系统85021- 计算机毕业设计项目选题推荐
  • (转)为C# Windows服务添加安装程序
  • (轉貼) 資訊相關科系畢業的學生,未來會是什麼樣子?(Misc)
  • .[backups@airmail.cc].faust勒索病毒的最新威胁:如何恢复您的数据?
  • .net core webapi 部署iis_一键部署VS插件:让.NET开发者更幸福
  • .NET Core WebAPI中使用Log4net 日志级别分类并记录到数据库
  • .NET Core WebAPI中使用swagger版本控制,添加注释
  • .net core 实现redis分片_基于 Redis 的分布式任务调度框架 earth-frost
  • .NET Core 网络数据采集 -- 使用AngleSharp做html解析
  • .net on S60 ---- Net60 1.1发布 支持VS2008以及新的特性
  • .Net 访问电子邮箱-LumiSoft.Net,好用
  • .NET/C# 避免调试器不小心提前计算本应延迟计算的值
  • .NET/C# 使窗口永不激活(No Activate 永不获得焦点)