2011-11-02 126 views
7

我想知道Boost.Format是否支持使用固定寬度/預分配的緩衝區作爲輸出,而不是由lib本身管理的動態緩衝區?是否可以使用預分配緩衝區的Boost.Format?

也就是說,正常情況下你會怎麼做:

boost::format myfmt("arg1: %1%/arg2: %2%"); 
// e.g.: 
cout << (myfmt % 3.14 % 42); 
// or 
string s = boost::str(myfmt % "hey!" % "there!"); 

所以升壓:格式LIB將自動完成分配足夠的空間和管理「輸出緩衝區」爲你的。

我想知道是否有任何方式使用與Boost.Format庫一個預定義的非動態緩衝區,也就是這樣的:

const size_t buf_sz = 512; 
char big_enough[buf_sz]; 
boost::format myfmt("arg1: %1%/arg2: %2%"); 
myfmt.attach_buffer(big_enough, buf_sz); 
myfmt % "hey!" % "there!" 
// big_enough buffer now contains the result string 

我知道我可以通過例子只是篩選,該文檔和來源,但除了缺乏時間atm。 (以及錯過某些東西的可能性)知道以下內容會很有趣: 如果不可能,如果有人能解釋爲什麼(如果存在/具體的是什麼) - 這是故意的嗎?它不符合API嗎? ...?

聲明:這個問題是不是關於性能!

+0

你要什麼,當你運行的空間會發生什麼?對於一個固定的buff,我會使用snprintf,但這就是我:) – nhed

+0

@nhed如果它不合適,庫可以/可以拋出一個異常或只是停止填充緩衝區(類似於[選項](http:///www.boost.org/doc/libs/1_47_0/libs/format/doc/format.html#exceptions)已提供) –

+0

我不確定那些例外情況適用於目標緩衝區 – nhed

回答

4

初步設想

望着source看來你可以用你自己的分配器,然後使用的boost::format內部流(internal_streambuf_t)。這對你的情況足夠好嗎?

例如,你可以使用類似的libstdC++ array_allocator

不幸的是boost::format還使用了幾個std::vector不使用它可以在你的情況下,問題的自定義分配器?

如何boost::format工作

我看着的boost::format的來源,這是它如何工作(以下描述爲str()<<電話要麼str()或使用標準std::ostream東西):

  • 格式類有時使用自定義分配器,有時使用默認分配器
  • 當所有參數和格式字符串分開時,將str()稱爲它cr eates新std::string並使其使用自定義分配器
  • 它,然後附加在格式字符串的所有參數和靜態串件結果字符串
  • 最後卻由值返回結果字符串足夠大的結果

因此,最終的結果字符串並不存儲在format類中,而是在需要時創建。

所以,即使您在使用自定義分配器時可以找到結果字符串的位置,它也只能在調用str()之後/期間使用。 這應該解釋爲什麼它是不可能的:格式化結果永遠不會存儲在類的「輸出緩衝區」中。

它爲什麼會這樣工作

他們爲什麼這樣做,我不知道。我認爲這是因爲只有在知道所有參數後才能創建結果,這會浪費空間來存儲結果,並且對於給定的格式/參數組合,您可能只需要一次結果。因此,在需要時創建它並不會導致額外的工作,因爲通常只會調用str()一次。

解決方案

  • 創建圍繞str()<<一些包裝和結果複製到您的固定緩衝
  • 使用stream_buffer爲「流」串入緩衝區(見下面的例子)
  • 繼承該類並添加您自己的str()函數,該函數將結果存儲在固定緩衝區中。

使用可能的解決方法boost::iostreams(測試):

#include <iostream> 
#include <boost/format.hpp> 
#include <boost/iostreams/stream.hpp> 

int main() 
{ 
    char buffer[100]; 

    boost::iostreams::stream<boost::iostreams::array_sink> 
     stream(buffer, sizeof(buffer)); 

    stream << (boost::format("arg1 = %1%") % 12.5); 
    stream << '\0'; // make sure buffer contains 0-terminated string 

    std::cout << buffer << std::endl;  
} 
+0

有用的信息。我認爲分配器的一個小問題是,他們只能通過bad_alloc報告失敗,對嗎? –

+0

@Martin:我認爲你是對的。另外,我研究了格式的來源,我認爲使用分配器很難做到。我用我發現的東西更新了我的答案。 – rve

+0

幹得好!我是否正確理解你:每次調用'.str()'時都會重新構建輸出字符串? –

相關問題