2017-08-10 205 views
0

我正在考慮在我們的項目中提出以下作爲sprintf/snprintf的替代方案。strprintf - 這個實現是否安全和便攜?

其動機是消除考慮緩衝區大小的需要,並儘可能地保留原始的便利性。

std::string strprintf(const char *fromat, ...) 
{ 
    std::string s; 
    s.resize(128); // best guess 
    char *buff = const_cast<char *>(s.data()); 

    va_list arglist; 
    va_start(arglist, fromat); 
    auto len = vsnprintf(buff, 128, fromat, arglist); 
    va_end(arglist); 

    if (len > 127) 
    { 
     va_start(arglist, fromat); 
     s.resize(len + 1); // leave room for null terminator 
     buff = const_cast<char *>(s.data()); 
     len = vsnprintf(buff, len+1, fromat, arglist); 
     va_end(arglist); 
    } 
    s.resize(len); 
    return s; // move semantics FTW 
} 

此代碼是否有任何固有問題?

使用示例:

auto s = strprintf("Hello %d world", 777); 
+0

*「方便的原始」* - 這是非常值得商榷的。 – StoryTeller

+0

看起來技術上是正確的,但如果緩衝區超過128字節上限,性能似乎不是很高。它再次調用vsnprintf,使該函數花費兩倍的時間。你必須權衡這裏的便利性和性能。此外,您返回的字符串將被再次複製 - 這進一步影響了性能。 – Freakyy

+0

返回值具有移動語義,所以不應該有另一個副本。 – CplusPuzzle

回答

0

原來,有對這個已經在這裏很多討論:

std::string formatting like sprintf

主觀上,我的版本看起來還是比大多數的東西有更簡潔,而且它的功能與該線程上的一些建議解決方案相同。