[英]How do I safely format floats/doubles with C's sprintf()?
我將我的一個C ++庫移植到一個有點不穩定的編譯器 - 它不支持字符串流,或者像snprintf()
這樣的C99功能。 我需要將int
, float
等值格式化為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;
}
相關問題:
編譯器是否支持ecvt
, fcvt
或gcvt
任何一個? 它們有點奇特, ecvt
,但是它們有自己的緩沖區( ecvt
, fcvt
)和/或你可能會很幸運,並且發現系統頭文件,如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.