天文數字下的bug 檔案的大小的顯示

2021-06-21 13:53:10 字數 3478 閱讀 3903

原始的**來自:【morewindows工作筆記5】strformatbytesize64 高階大氣的顯示檔案大小

但是**中有乙個bug,你看出什麼問題來了嗎?

// 【morewindows工作筆記5】strformatbytesize64 高階大氣的顯示檔案大小

#include #include #include #pragma comment(lib, "shlwapi.lib")

void normfilesize(longlong file_length, char* buffer, int buffer_size) ;

double length = static_cast(file_length);

int i = 0;

while (i < arraysize(size_name) && length > base_number)

sprintf(buffer, "%lf %s", length, size_name[i]);

}int main()

; normfilesize(file_length, file_length_str1, 100);

printf("%15s ", file_length_str1);

wchar file_length_str2[100] = ;

strformatbytesizew(file_length, file_length_str2, 100); // strformatbytesizew會截斷尾數

printf("%ls\n", file_length_str2); // 還可以試試strformatkbsize,這個只用kb來表示

file_length *= 11;

}return 0;

}

看來只有在極端情況下才會出現

現在我們就來再現問題

首先有個疑問: longlong 能表示的最大值是多少?

是9223372036854775807(具體看

改動一下**

將static char* size_name = ; 的static去掉

將9223372036854775807代入函式normfilesize()

[檔案為testprintf.cpp]

#include #include #include #include #include #include #pragma comment(lib, "shlwapi.lib")

void normfilesize(longlong file_length, char* buffer, int buffer_size) ;

double length = static_cast(file_length);

int i = 0;

while (i < arraysize(size_name) && length > base_number)

sprintf(buffer, "%lf %s", length, size_name[i]);

}int main()

; wchar file_length_str2[100] = ;

//for (int i = 0; i < 10; i++)

//file_length=9223372036854775807;

normfilesize(file_length, file_length_str1, 100);

return 0;

}

執行後就會出現

接著我們要來抓鬼--為什麼會出現這個問題呢?

在下面所示的這個迴圈內,i值一直都是合法的,而且語義上完全沒有問題,

while (i < arraysize(size_name) && length > base_number) 

但是迴圈下面的**引用了這個變數,一般情況下,不會有問題,然後有人在問---我們一定要把沒問題的東西測出問題來嗎?但是如果在極端情況下,比如代入很大的值,於是退出迴圈後i==arraysize(size_name),我們知道,c++的陣列const int max_index=1000;int array[max_index]下標範圍是0~max_index-1,元素為array[0],array[1],...array[max_index-1],使用array[max_index]就是越界!!!解決辦法就是在越界前結束迴圈:

while (i < arraysize(size_name)-1 && length > base_number) 

附上完整函式進化版本

#include #include #include tchar* bytes2stringex(const ularge_integer ullsizeinbytes,tchar *lpszsizeinfo)//strformatbytesize64在ansi工作不正常

; int i = 0;

int max_index=sizeof(unitname)/sizeof(unitname[0]) ; //int max_index2=arraysize(unitname);

while ( i1024.0 )

tchar *un=unitname[i];//雖然上面的while中i不會超出max_index但是,當超出時,下面引用到的正是超出的這個下標

#pragma warning(disable:4996)

_sntprintf(lpszsizeinfo,10230, text("%lf %s"),filesize, un);

return lpszsizeinfo;

}

tchar* bytes2stringex2(const ularge_integer ullsizeinbytes,tchar *lpszsizeinfo)//strformatbytesize64在ansi工作不正常

; const int unit_max_index=sizeof(storageunit)/sizeof(storageunit[0]);

const long double base_number = 1024.0;

int i = 0;

while ( ibase_number )//bug fixed:雖然上面的while中i不會超出unit_max_index但是,當超出時,下面引用到的正是超出的這個下標所以要減一:i

#pragma warning(disable:4996)

_stprintf(lpszsizeinfo,text("%lf%s"),filesize, storageunit[i]);

return lpszsizeinfo;

}

int _tmain()

天文台出現的bug除錯

1 利用感興趣區域roi的的兩種定義方法是 出現了opencv error line248 這個錯誤,當時一直以為是影象畫素座標越界導致的,後來發現用mat 來定義的時候,必須是先定義height再定義width,也就是先定義rows再定義cols,受到了中文思維長 寬的影響!2 最開始在drawh...

linux下怎樣得到檔案的大小

1.shell 得到已經使用的磁碟空間,以位元組為單位 ifdef linux sprintf cmd,cd s find name xargs ls l awk end str filepath.c str sprintf cmd,du s s awk str filepath.c str end...

linux下C獲取檔案的大小

獲取檔案大小這裡有兩種方法 方法一 範例 cpp view plain copy print?unsigned long get file size const char path 方法二 範例 c sharp view plain copy print?include unsigned long ...