2010-05-12 109 views
1

我將double轉換一個字符的字符串:如何防止緩衝區溢出將double轉換爲char?

char txt[10]; 
double num; 

num = 45.344322345 

sprintf(txt, "%.1f", num); 

,並使用「.1F」截斷小數位,以十分之一的數字。
即 - txt包含45.3

我通常在sprintf中使用精度來確保字符緩衝區沒有溢出。 我怎麼能這樣做也截斷小數,而不使用snprintf?

(即如果num = 345694876345.3出於某種原因)

感謝

編輯如果num>緩存的結果不再是問題,只是不想崩潰。不確定在這種情況下最有意義的是什麼。

EDIT2我應該比在標籤中更清楚這是一個C程序。 我遇到了在C程序中使用snprintf的問題。 I don't want to add any 3rd party libraries.

+0

如果不能正確打印結果,您希望得到的結果是什麼? – 2010-05-12 00:13:49

回答

5

使用snprintf(),它會告訴你打印了多少個字節而不是。一般來說,您應該調整數組的大小,以便處理目標整數類型的最長字符串表示形式。如果事先不知道,請使用malloc()(或asprintf(),這是非標準的,但存在於許多平臺上)。

編輯如果格式超過給定的緩衝區

snprintf()會優雅地失敗,也不會溢出。如果你不需要處理,那麼只需使用它將解決你的問題。我想不出想要來處理這個問題,但是我再也沒有在做任何工作:)

1

爲什麼你想要沒有snprintf?無論您的格式字符串是否包含雙精度,另一個字符串或其他任何字符,都應該使用snprintf。據我所知,沒有理由不是來。

2

如果你絕對必須自己做,嘗試轉換之前計數數數字:

int whole = num; 
int wholeDigits = 0; 
do { 
    ++wholeDigits; 
} 
while (whole /= 10); 

double fraction = num - (int) num; 
int decimallDigits = 0; 
while (fraction > 0) { 
    ++decimalDigits; 
    fraction *= 10; 
    fraction = fraction - (int) fraction; 
} 

int totalLength = decimalDigits ? wholeDigits + decimalDigits + 1 : wholeDigits; 

你或許應該驗證此臨時代碼工作依靠它來防止崩潰之前像宣傳的那樣。正如其他人所說,我建議您使用snprintf或類似的東西,而不是我的代碼。

3

爲什麼不只是讓你的緩衝區足夠大,以保持雙倍的最大可能的字符串表示?

假設使用IEEE標準的浮點運算的64位雙精度浮點運算,其中52位用於尾數:2^52 = 4,503,599,627,370,500。所以我們需要16個字符來保存小數點前後的所有數字。 19考慮小數點,符號字符和空終止符。

我只會使用至少20個字符的緩衝區大小,然後繼續。

如果您需要使用科學記數法打印double,則需要爲指數添加足夠的空間。假設一個11位有符號指數,這是指數的另外4個字符加上指數和字母'E'的符號。在這種情況下,我只需要30個字符。

+0

我只是讓它40,繼續前進。除非它是一個數組,否則這40個字節比你的時間便宜很多。但我也喜歡snprintf。 – progrmr 2010-05-12 00:34:09