short si = -1;

sprintf(s, "%04X", si);

产生“FFFFFFFF”,怎么回事?因为spritnf 是个变参函数,除了前面两个

参数之外,后面的参数都不是类型安全的,函数更没有办法仅仅通过一个

“%X”就能得知当初函数调用前参数压栈时被压进来的到底是个4 字节的整

数还是个2 字节的短整数,所以采取了统一4 字节的处理方式,导致参数压

栈时做了符号扩展,扩展成了32 位的整数-1,打印时4 个位置不够了,就

把32 位整数-1 的8 位16 进制都打印出来了。如果你想看si 的本来面目,

那么就应该让编译器做0 扩展而不是符号扩展(扩展时二进制左边补0 而不

是补符号位):

sprintf(s, "%04X", (unsigned short)si);

就可以了。或者:

unsigned short si = -1;

sprintf(s, "%04X", si);

2. 浮点数的打印和格式控制是sprintf 的又一大常用功能,浮点数使用格式符”

%f”控制,默认保留小数点后6 位数字,比如:

sprintf(s, "%f", 3.1415926); //产生"3.141593"

但有时我们希望自己控制打印的宽度和小数位数,这时就应该使用:”

%m.nf”格式,其中m 表示打印的宽度,n 表示小数点后的位数。比如:

sprintf(s, "%10.3f", 3.1415626); //产生:" 3.142"

sprintf(s, "%-10.3f", 3.1415626); //产生:"3.142 "

sprintf(s, "%.3f", 3.1415626); //不指定总宽度,产生:"3.142"

注意一个问题,你猜

int i = 100;

sprintf(s, "%.2f", i);

会打出什么东东来?“100.00”?对吗?自己试试就知道了,同时也试试下面这个:

sprintf(s, "%.2f", (double)i);

第一个打出来的肯定不是正确结果,原因跟前面提到的一样,参数压栈时调

用者并不知道跟i相对应的格式控制符是个”%f”。而函数执行时函数本身

则并不知道当年被压入栈里的是个整数,于是可怜的保存整数i 的那4 个字

节就被不由分说地强行作为浮点数格式来解释了,整个乱套了。

3 .连接字符串

sprintf 的格式控制串中既然可以插入各种东西,并最终把它们“连成一

串”,自然也就能够连接字符串,从而在许多场合可以替代strcat,但

sprintf 能够一次连接多个字符串(自然也可以同时在它们中间插入别的内

容,总之非常灵活)。比如:

char* who = "I";

char* whom = "CSDN";

sprintf(s, "%s love %s.", who, whom); //产生:"I love CSDN. "

strcat 只能连接字符串(一段以’\0’结尾的字符数组或叫做字符缓冲,

null-terminated-string),

但有时我们有两段字符缓冲区,他们并不是以’\0’结尾。比如许多从第三

方库函数中返回的字符数组,从硬件或者网络传输中读进来的字符流,它们

未必每一段字符序列后面都有个相应的’\0’来结尾。如果直接连接,不管

是sprintf 还是strcat 肯定会导致非法内存操作,strncat 也至少要求第

一个参数是个null-terminated-string,那该怎么办呢?我们自然会想起前

面介绍打印整数和浮点数时可以指定宽度,字符串也一样的。比如:

char a1[] = {''''A'''', ''''B'''', ''''C'''', ''''D'''', ''''E'''', ''''F'''', ''''G''''};

char a2[] = {''''H'''', ''''I'''', ''''J'''', ''''K'''', ''''L'''', ''''M'''', ''''N''''};

如果:

sprintf(s, "%s%s", a1, a2); //Don''''t do that!

十有八九要出问题了。是否可以改成:

sprintf(s, "%7s%7s", a1, a2);

也没好到哪儿去,正确的应该是:

sprintf(s, "%.7s%.7s", a1, a2);//产生:"ABCDEFGHIJKLMN"

这可以类比打印浮点数的”%m.nf”,在”%m.ns”中,m 表示占用宽度(字

符串长度不足时补空格,超出了则按照实际宽度打印),n 才表示从相应的

字符串中最多取用的字符数。通常在打印字符串时m 没什么大用,还是点号

后面的n 用的多。自然,也可以前后都只取部分字符:

sprintf(s, "%.6s%.5s", a1, a2);//产生:"ABCDEFHIJKL"

(因为sprintf函数将输出写入到字符串s中,并以''''\0''''结束,所以生成的s

中有''''\0'''',所以可以用printf(s),而不用担心会出错)

在许多时候,我们或许还希望这些格式控制符中用以指定长度信息的数字是

动态的,而不是静态指定的,因为许多时候,程序要到运行时才会清楚到底

需要取字符数组中的几个字符,这种动态的宽度/精度设置功能在sprintf

的实现中也被考虑到了,sprintf 采用”*”来占用一个本来需要一个指定

宽度或精度的常数数字的位置,同样,而实际的宽度或精度就可以和其它被

打印的变量一样被提供出来,于是,上面的例子可以变成:

sprintf(s, "%.*s%.*s", 7, a1, 7, a2);

或者:

sprintf(s, "%.*s%.*s", sizeof(a1), a1, sizeof(a2), a2);

实际上,前面介绍的打印字符、整数、浮点数等都可以动态指定那些常量值,

比如:

sprintf(s, "%-*d", 4, ''''A''''); //产生"65 "

sprintf(s, "%#0*X", 8, 128); //产生"0X000080","#"产生0X

sprintf(s, "%*.*f", 10, 2, 3.1415926); //产生" 3.14"

sprintf函数的用法linux,sprintf函数用法解析相关推荐

  1. linux signal用法,Linux 信号 signal 用法详解及注意事项

    Linux 信号 signal 用法详解及注意事项 1) SIGHUP 本信号在用户终端连接 (正常或非正常) 结束时发出, 通常是在终端的控 制进程结束时, 通知同一 session 内的各个作业, ...

  2. linux fork 用法,Linux系统调用fork()用法详解

    linux 系统调用fork()的用法详解 Linux系统调用fork()用法详解 1. 先看下面代码: #include #include //pid_t类型定义 #include //函数fork ...

  3. linux下crontab命令的用法,linux 定时任务crontab用法详解

    linux 定时任务crontab用法详解 linux中crontab命令用于设置周期性被执行的指令,该命令从标准输入设备读取指令,并将其存放于"crontab"文件中,以供之后读 ...

  4. linux中split函数用法,Linux csplit 命令用法详解-Linux命令大全(手册)

    csplit Linux csplit命令用于分割文件. 将文件依照指定的范本样式予以切割后,分别保存成名称为xx00,xx01,xx02-的文件.若给予的文件名称为"-",则cs ...

  5. linux格式化硬盘函数,关于用linux C函数实现查看磁盘空间大小

    http://blog.163.com/chi.139@126/blog/static/778267772010627112031918/ 不想用Linux 的命令获得磁盘的大小,而是用函数得到磁盘的 ...

  6. linux 脚本scp用法,Linux scp命令用法及实例分享

    Linux下scp的用法 scp就是secure copy,一个在linux下用来进行远程拷贝文件的命令. 有时我们需要获得远程服务器上的某个文件,该服务器既没有配置ftp服务器,也没有做共享,无法通 ...

  7. linux中uniq的用法,linux uniq命令用法

    uniq命令: 对指定的ASCII文件或标准输入进行唯一性检查,以判断文本文件中重复出现的行,常用于分析日志:查看tcp各个状态连接数,ip或域名连接数排名等等场景,一般与 sort 命令结合使用. ...

  8. linux命令sort的用法,Linux sort命令用法详解

    sort命令将许多不同的域按不同的列顺序分类.sort命令以空格作为字段分隔符,将一行分割为多个关键字对文件进行排序.需要注意的是sort命令并不对文件内容进行实际的排序(即文件内容没有修改),只是将 ...

  9. linux resize用法,Linux resize2fs 命令用法详解-Linux命令大全(手册)

    resize2fs resize2fs命令被用来增大或者收缩未加载的"ext2/ext3"文件系统的大小.如果文件系统是处于mount状态下,那么它只能做到扩容,前提条件是内核支持 ...

  10. linux shell ${}简单用法,Linux shell ${}简单用法

    为了完整起见,我这里再用一些例子加以说明 ${ } 的一些特异功能: 假设我们定义了一个变量为: file=/dir1/dir2/dir3/my.file.txt 我们可以用 ${ } 分别替换获得不 ...

最新文章

  1. 文字超长自动加省略号的css写法
  2. 【干货下载】大数据分析——如何消除金融不确定性
  3. [Poi2011]Tree Rotations线段树合并
  4. 库存商品表html源码,JSP+Servlet+数据库的方式完成一个简易的库存商品管理系统...
  5. [CodeForces - 950D]A Leapfrog in the Array(思维)
  6. ROS学习笔记八:创建ROS msg和srv
  7. 华为 “OSPF” 被动接口配置
  8. MySQL中数据表的查操作
  9. spring相关—IOC容器—使用注解配置bean
  10. 中值滤波_中值滤波原理
  11. 算高差改正数的计算机程序,水准测量中测量高差的改正数怎么计算?
  12. 游戏开发 | 基于 EasyX 库开发经典90坦克大战游戏
  13. aardio - 【库】FlexCell表格组件
  14. 剪映专业版 for Mac(视频剪辑工具)
  15. Luat模块应用手册-指南-Luat二次开发教程指南-功能开发教程-虚拟AT
  16. 3名院士被处理,院士改革确实动真格了!
  17. 自己编一个大乐透选号器
  18. STM32单片机智能语音温控摇头电风扇落地扇可红外遥控可PWM调速定时温度显示
  19. 疯狂的程序员(绝影)
  20. QNX系统ARM架构上protobuf文件读取乱码

热门文章

  1. NotifyIcon用法
  2. 低速硬件接口之RS485接口自收发隔离多节点分享
  3. 开关电源matlab仿真,用数学方法建立一种开关电源全系统的仿真模型
  4. 崩坏3区号+86_中国大陆国际区号是“ +86”,还是“ +086”、“ +0086”
  5. 如何使用matlab绘制晶胞结构示意图
  6. Google翻译Chrome插件
  7. 新挑战新思路|山石网科互联网企业安全SD-WAN解决方案
  8. 世界500强面试推理题求答案
  9. 财智V6.0(完美破解序列号特别版)
  10. 计算机类毕业论文中期检查,计算机类毕业论文中期检查表