printf打印输出null问题的跟踪
最近在工作中,遇到一处 printf输出有null的情况,在此记录一下,问题分析的过程。
测试代码很简单,本机为64位操作系统:
#include <stdio.h>
#include <time.h>
int main(){
char addr[128] = "127.0.0.1";
printf("1. output: %s \n", addr);
printf("2. %ld output: %s \n", 100, addr);
printf("3. %ld output: %s \n", time(NULL), addr);
return 0;
}
输出结果为:

前两个很好理解,第三项输出有 (null),这里就很奇怪了,后面的addr变量没有正确输出。
继续一些测试,
__time32_t test_time_t_32_return()
{
return 100;
}
__time64_t test_time_t_64_return()
{
return 100;
}
printf("__time32_t:%d __time64_t:%d\n", sizeof(__time32_t), sizeof(__time64_t));
printf("6. %ld output: %s \n", test_time_t_32_return(), addr);
printf("7. %ld output: %s \n", test_time_t_64_return(), addr);

上说结果表明:当time(NULL)返回32位数时,printf输出是正确的,返回64位数字时,输出为空。
经过查找资料,得知printf输出格式化%ld只能输出32位数字,当输入内容为64位数字时,应当会截取低32位,当做%ld的输入,而高32位内容为空,会传递给后一个参数%s,当%s接收到输入0,会输出(null).
下面经过一些实际代码来验证下:
__time64_t test = 0x12345678abcdabcd;
printf("7. low 32: %lx high 32: %lx\n", test);
printf("8. 64 interger: %llx \n", test);
printf("9: %s", 0);
输出内容如下:

printf输出的格式控制字符,%lx以16进制打印输出32位数字,%llx以16进制打印输出64位数字。
printf的格式控制字符,%s在内部解析时,应该有判断为空的情况,传入为空字符串,会转为输出(null)字符串。以上是猜测,让我们深入源码来了解下:
在windows上,VC编译器会附带C标准库的实现,通过查找,初步定位在D:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\crt\src\printf.c文件中,将此文件拉入VS2010,在printf函数的入口处打上断点,开启调试就可以进入源码调试。
我们本次的兴趣点在输出(null)的情况,因此,直接跟进去查找(null)字符串出现和使用的地方即可:
空字符串定义如下图:

空字符串转换如下图:

小结:打印输出时,注意32位整数和64位整数的打印方式区分。
printf打印输出null问题的跟踪的更多相关文章
- 转:printf打印输出2进制
转自:C语言中printf直接打出2进制数是%什么?16进制是什么? void print_2(int val2) { unsigned ; //从低位到高位,低端字节计算机 ; k <= ; ...
- printf打印输出
int PrintVal = 9; /*按整型输出,默认右对齐*/ printf("%d\n",PrintVal); /*按整型输出,补齐4位的宽度,补齐位为空格 ...
- shell脚本--echo和printf打印输出
bash&shell系列文章:http://www.cnblogs.com/f-ck-need-u/p/7048359.html 注:本文关于引号等特殊符号的处理仅仅只是几个例子,想要彻底搞明 ...
- echo和printf打印输出
[root@node2 scprits]# echo Hello World! Hello World! [root@node2 scprits]# echo 'Hello World!' Hello ...
- g++中宏NULL究竟是什么?
NULL是个指针,还是个整数?0?或(void*)0?答案是和g++版本有关.g++ 4.6支持C++11,引入了nullptr,也许会发生变化. 可以写段简单代码求证一下: #include < ...
- 使用SWO代替UART,实现Printf打印功能
JTAG接口中,有个SWO引脚,一直没有在意,也没有去研究过是干嘛用的.直到发现ST-LINK V2-1上也有个SWO引脚,于是去研究学习它的作用,用起来相比UART方得便多. 本文内容已经整理成PD ...
- Trace-语句启动Profiler中暂停的跟踪会出现什么状况
2016-09-08 22:09 整理,未发布Profiler创建客户端跟踪.常规页不保存文件.不勾选服务器处理跟踪数据:事件选择RPC:Completed和SQL:BatchCompleted,列筛 ...
- struts请求源码的跟踪
最近工作任务不是很紧,时间也不能白白浪费,以前常用的struts2框架源码没去了解过,所以就跟踪一下struts2的整个执行过程.由于本人也是抱着学习的态度来阅读掩码,若文章在表述和代码方面如有不妥之 ...
- SQL 跟踪方法相关介绍
oracle sql跟踪方法:1.sql_trace打开跟踪:alter session set sql_trace=true;为跟踪文件做标记:alter session set tracefile ...
随机推荐
- 潭州课堂25班:Ph201805201 爬虫基础 第七课 Python与常见加密方式 (课堂笔记)
打开图形界面 18版 Python与常见加密方式 前言 我们所说的加密方式,都是对二进制编码的格式进行加密的,对应到Python中,则是我们的Bytes. 所以当我们在Python中进行加密操作的时 ...
- netty如何知道连接已经关闭,socket心跳,双工?异步?
https://stackoverflow.com/questions/10240694/java-socket-api-how-to-tell-if-a-connection-has-been-cl ...
- 淘宝bug bug bug
手机淘宝(苹果版)出现了一个挺耀眼的bug...... 待评价有九个,如图 点进去评价6个之后,还有三个 再出来,待评价还是有九个. 重新打开,下拉刷新都不能改变
- Math类操作数据
Math 类位于 java.lang 包中,包含用于执行基本数学运算的方法, Math 类的所有方法都是静态方法,所以使用该类中的方法时,可以直接使用类名.方法名,如: Math.round(); 常 ...
- linux目录的权限
Answer: When applying permissions to directories on Linux, the permission bits have different meanin ...
- 微信小程序 scroll-view 实现锚点跳转
在微信小程序中,使用 scroll-view 实现长页面的标记跳转,官方文档中没有例子演示,锚点标记主要是使用<scroll-view> 的 scroll-into-view 属性. 实现 ...
- android学习笔记(8)linearlayout与android:layout_weight学习
一,linearlayout 线性布局,布局文件里设置多个linearlayout来达到总体线性布局的风格. android:gravity="right"对齐方式,居右对齐,gr ...
- Android apk签名的两种方法
编辑推荐:稀土掘金,这是一个针对技术开发者的一个应用,你可以在掘金上获取最新最优质的技术干货,不仅仅是Android知识.前端.后端以至于产品和设计都有涉猎,想成为全栈工程师的朋友不要错过! 为了保证 ...
- grid - gap
grid-gap默认还有两个参数 如果grid写默认方式,则行.列都会使用相同的单位 如果grid写两个参数,则行和列各自生效 如果grid写行方式,则仅有行生效 如果grid写列方式,则仅有列生 ...
- 【Zookeeper】源码分析之Leader选举(二)之FastLeaderElection
一.前言 前面学习了Leader选举的总体框架,接着来学习Zookeeper中默认的选举策略,FastLeaderElection. 二.FastLeaderElection源码分析 2.1 类的继承 ...