2011-08-21 43 views
2

我有一個需要序列int, double, long, and float 成字符緩衝區,這是我目前做的方式
如何數字數據序列轉換成char *

int value = 42; 
char* data = new char[64]; 
std::sprintf(data, "%d", value); 

// check 
printf("%s\n", data); 

首先我不知道這是否是最好的這樣做的方式,但我的直接問題是確定緩衝區的大小。
這種情況下的數字64完全是任意的。 如何知道傳遞的數字的確切大小,以便我可以分配確切的內存;不是更多不少於需要?

C或C++解決方案都可以。

編輯
基於約翰回答(分配足夠大的緩衝區。)下面,我想這樣做

char *data = 0; 
int value = 42; 
char buffer[999]; 
std::sprintf(buffer, "%d", value); 
data = new char[strlen(buffer)+1]; 
memcpy(data,buffer,strlen(buffer)+1); 

printf("%s\n", data); 

在速度的代價或許是避免了浪費。並沒有完全解決潛在的溢出
或者我可以只使用足以代表該類型的最大值。

+0

它看起來不是標準函數,而是'asprintf',如果可用,看起來好像可以很好地解決您的問題。 – icktoofay

+0

@Bala:這會給你在內存中的大小*,他詢問sprintf給出的輸出大小以分配足夠大的緩衝區。 –

+0

你真的想要從字面上序列化數字數據嗎?至少你可以存儲精確的二進制值,也許是Base64編碼的。這也有一定的規模。 –

回答

4

在C++中,你可以使用一個字符串流,並停止擔心緩衝區的大小:

#include <sstream> 

... 

std::ostringstream os; 
int value=42; 
os<<42; // you use string streams as regular streams (cout, etc.) 
std::string data = os.str(); // now data contains "42" 

(如果你願意,你可以通過c_str()方法得到的std::string一個const char *


在C中,您可以使用snprintf來「僞造」寫入並獲取要分配的緩衝區的大小;事實上,如果您傳遞0作爲snprintf的第二個參數,則可以將NULL作爲目標字符串傳遞,並獲得將寫入的字符作爲返回值。所以在C你可以做:

int value = 42; 
char * data; 
size_t bufSize=snprintf(NULL, 0 "%d", value)+1; /* +1 for the NUL terminator */ 
data = malloc(bufSize); 
if(data==NULL) 
{ 
    // ... handle allocation failure ... 
} 
snprintf(data, bufSize, "%d", value); 
// ... 
free(data); 
+0

這絕對是一個有效的方法,我已經使用它,但後來我認爲這是太多的箍:首先ostringstream然後調用str()然後調用c_str()然後最後調用strcpy填充緩衝區。 – luis

+0

@luis:我擴大了答案,看看第二種方法。順便說一下,這些數據的「最終目的地」是什麼?也許你可以避免一些C++解決方案的額外步驟...... –

+1

Boost.lexical_cast很好地包裝了所有這些箍筋。 –

-2

我會序列化到一個'夠大'的緩衝區,然後複製到一個分配的緩衝區。在C

char big_buffer[999], *small_buffer; 
sprintf(big_buffer, "%d", some_value); 
small_buffer = malloc(strlen(big_buffer) + 1); 
strcpy(small_buffer, big_buffer); 
+0

這很有趣。我將嘗試使用相同技術的C++方法 – luis

+0

不要將您的臨時緩衝區過小,呃? –

+0

你如何確定什麼是「足夠大」?原則上,'int'可能會大到足以溢出999字節的緩衝區,儘管這當然不太可能。更現實的說,有很多方法可以計算出一個更小的上限,但在編譯時做得很好並不重要。 –