簡體   English   中英

如何使用C的sprintf()安全地格式化浮點數/雙打?

[英]How do I safely format floats/doubles with C's sprintf()?

我將我的一個C ++庫移植到一個有點不穩定的編譯器 - 它不支持字符串流,或者像snprintf()這樣的C99功能。 我需要將intfloat等值格式化為char* ,並且唯一可用的選項似乎是1)使用sprintf() 2)手動滾動格式化過程。

鑒於此,如何確定(在編譯或運行時)格式化浮點值需要多少字節? 我的庫可能用於模糊測試,因此它需要處理異常或極端值。

或者,是否有一個小的(100-200行首選), snprintf()可移植實現,我可以簡單地與我的庫捆綁?

理想情況下,我最終會得到基於snprintf()的普通代碼,或類似的東西:

static const size_t FLOAT_BUFFER_SIZE = /* calculate max buffer somehow */;

char *fmt_double(double x)
{
    char *buf = new char[FLOAT_BUFFER_SIZE + 1];
    sprintf(buf, "%f", x);
    return buf;
}

相關問題:

編譯器是否支持ecvtfcvtgcvt任何一個? 它們有點奇特, ecvt ,但是它們有自己的緩沖區( ecvtfcvt )和/或你可能會很幸運,並且發現系統頭文件,如VC ++中那樣,定義了最大字符數gcvt將生產。 你可以從那里拿走它。

如果做不到這一點,我會根據提供的代碼考慮以下內容。 對於雙人來說,500個字符非常保守; 有效值大約是10 ^ -308到10 ^ 308,所以即使通過打印出所有數字來確定實現是煩人的,也應該沒有溢出。

char *fmt_double(double d) {
    static char buf[500];
    sprintf(buf,"%f",d);
    assert(buf[sizeof buf-1]==0);//if this fails, increase buffer size!
    return strdup(buf);
}

這並不完全提供任何驚人的保證,但它應該是非常安全的(tm)。 不幸的是,我認為這種方法與這種方法一樣好。 但如果您習慣於定期運行調試版本,那么至少應該對任何問題進行預警......

我認為GNU Libiberty就是你想要的。 您可以只包含snprintf的實現。

vasprintf.c - 152 LOC。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM