最近在工作中,遇到一处 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问题的跟踪的更多相关文章

  1. 转:printf打印输出2进制

    转自:C语言中printf直接打出2进制数是%什么?16进制是什么? void print_2(int val2) { unsigned ; //从低位到高位,低端字节计算机 ; k <= ; ...

  2. printf打印输出

    int PrintVal = 9;    /*按整型输出,默认右对齐*/    printf("%d\n",PrintVal);    /*按整型输出,补齐4位的宽度,补齐位为空格 ...

  3. shell脚本--echo和printf打印输出

    bash&shell系列文章:http://www.cnblogs.com/f-ck-need-u/p/7048359.html 注:本文关于引号等特殊符号的处理仅仅只是几个例子,想要彻底搞明 ...

  4. echo和printf打印输出

    [root@node2 scprits]# echo Hello World! Hello World! [root@node2 scprits]# echo 'Hello World!' Hello ...

  5. g++中宏NULL究竟是什么?

    NULL是个指针,还是个整数?0?或(void*)0?答案是和g++版本有关.g++ 4.6支持C++11,引入了nullptr,也许会发生变化. 可以写段简单代码求证一下: #include < ...

  6. 使用SWO代替UART,实现Printf打印功能

    JTAG接口中,有个SWO引脚,一直没有在意,也没有去研究过是干嘛用的.直到发现ST-LINK V2-1上也有个SWO引脚,于是去研究学习它的作用,用起来相比UART方得便多. 本文内容已经整理成PD ...

  7. Trace-语句启动Profiler中暂停的跟踪会出现什么状况

    2016-09-08 22:09 整理,未发布Profiler创建客户端跟踪.常规页不保存文件.不勾选服务器处理跟踪数据:事件选择RPC:Completed和SQL:BatchCompleted,列筛 ...

  8. struts请求源码的跟踪

    最近工作任务不是很紧,时间也不能白白浪费,以前常用的struts2框架源码没去了解过,所以就跟踪一下struts2的整个执行过程.由于本人也是抱着学习的态度来阅读掩码,若文章在表述和代码方面如有不妥之 ...

  9. SQL 跟踪方法相关介绍

    oracle sql跟踪方法:1.sql_trace打开跟踪:alter session set sql_trace=true;为跟踪文件做标记:alter session set tracefile ...

随机推荐

  1. vi 命令 行首、行尾

    vim 跳到行首 : 数字 0 vim跳到行位 : $  [Shift + 4]

  2. 3DMax 2014中文版安装破解教程

    周末的时候,因为帮忙别人做动画,要用到3dmax.然后发现自己真的很菜啊....弄了好久,然后终于阔以了,以后在慢慢研究.贴出详细的步骤: . 1.如果没有软件,就请自行下载[百度上很多的] 2.双击 ...

  3. Facebook's React vs AngularJS: A Closer Look

    When we launched React | A JavaScript library for building user interfaces two weeks ago there were ...

  4. delphi Tdxribbon 设置背景和skin 皮肤

    https://blog.csdn.net/maxwoods/article/details/8592389 http://www.cnblogs.com/baoluo/archive/2011/04 ...

  5. DateTables的服务器分页

    function InitTable() { var table = $('#tbl_users').DataTable(); if ($.fn.dataTable.isDataTable('#tbl ...

  6. Spring---面向切面编程(AOP模块)

    Spring AOP 简介 如果说 IoC 是 Spring 的核心,那么面向切面编程就是 Spring 最为重要的功能之一了,在数据库事务中切面编程被广泛使用. AOP 即 Aspect Orien ...

  7. Fibratus:一款功能强大的Windows内核漏洞利用和跟踪工具

    今天给大家介绍的是一款名叫Fibratus的开源工具,广大研究人员可以使用这款功能强大的工具来进行Windows内核漏洞利用.挖掘与跟踪. Fibratus这款工具能够捕捉到绝大多数的Windows内 ...

  8. iOS开发-UIImageView高效设置Radius

    圆角的设置在iOS中随处可见,开发的时候也很方便,但是有的时候如果一个页面有大量的需要设置圆角的图片,容易产生性能问题,UIImageView ios9.0之前设置圆角是会产生离屏渲染的,9.0之后不 ...

  9. 当echarts的legend字数过多的时候变成省略号

    legend: { data: ['国有土地使用','食品药品安全','生态环境和资源保护','国有财产保护'], orient: 'horizontal', left: '10', bottom:' ...

  10. 了解 JavaScript (3)- 马上开始

    之前演示了一个 Hello World 程序,而后讲解了一些基础概念,下面开始一些基础工作. 将脚本放在哪里 脚本可以放置在两个位置 <head></head>之间,头脚本(h ...