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;
}

輸出結果為:
printf輸出

前兩個很好理解,第三項輸出有 (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);

ceshi

上說結果表明:當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位整數的打印方式區分。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM