2010-08-13 48 views
10
print2fp(const void *buffer, size_t size, FILE *stream) { 

if(fwrite(buffer, 1, size, stream) != size) 
    return -1; 

return 0; 
} 

如何將數據寫入字符串流而不是文件流?C中的字符串流

+0

類似我剛纔的問題:http://stackoverflow.com/questions/1741191/creating-a-file-stream-that-results-in-a-string – Edmund 2010-08-13 23:18:59

+0

既然你沒有POSIX 2008字符串流功能,你可能運氣不好 - 除非你可以找到一個模擬它們的庫來達到你的目的。 – 2010-08-14 00:55:11

+1

** String Streams **
http://www.gnu.org/s/libc/manual/html_node/String-Streams.html – 2010-08-13 22:44:12

回答

2

簡單地使用來自REFFERENCE的sprintf http://www.cplusplus.com/reference/cstdio/sprintf/

例如:

#include <stdio.h> 

int main() 
{ 
    char buffer [50]; 
    int n, a=5, b=3; 
    n=sprintf (buffer, "%d plus %d is %d", a, b, a+b); 
    printf ("[%s] is a string %d chars long\n",buffer,n); 
    return 0; 
} 

輸出:

[5加3圖8是13個字符長

更新的字符串:根據意見中的建議: 使用snprinft,因爲它更安全(防止緩衝區溢出攻擊)並且便攜。

#include <stdio.h> 

int main() 
{ 
    int sizeOfBuffer = 50; 
    char buffer [sizeOfBuffer]; 
    int n, a=5, b=3; 
    n= snprintf (buffer, sizeOfBuffer, "%d plus %d is %d", a, b, a+b); 
    printf ("[%s] is a string %d chars long\n",buffer,n); 
    return 0; 
} 

注意的snprintf秒的說法實際上是允許的最大規模的使用,所以你可以把它放到一個較低的值比sizeOfBuffer,但是你的情況下,它是不必要的。 Snprintf只寫入SizeOfBuffer -1字符並使用終止字符的最後一個字節。

而只是爲了激怒從embbed和安全部門大家好,這裏是http://www.cplusplus.com/reference/cstdio/snprintf/

+2

不要使用sprintf(),幾乎任何使用sprintf()都會爆炸一段時間。使用asprintf()代替它,它會爲你提供一個所需長度的緩衝區。 – cmaster 2013-06-15 08:11:27

+3

或便攜式代碼中的'snprintf'。另外,請不要鏈接到cplusplus.com,該網站是充滿錯誤。 cppreference.com更好。 – 2013-06-15 09:51:30

+0

另外,sprintf和vsprintf有安全問題。 http://www.codecogs.com/library/computing/c/stdio.h/printf.php?alias=snprintf **「** sprintf和vsprintf函數很容易被誤用,惡意用戶可以任意使用通過緩衝區溢出攻擊來改變正在運行的程序的功能,因爲sprintf和vsprintf假設一個無限長的字符串,所以調用者必須小心,不要溢出實際空間;這通常很難保證,爲了安全起見,程序員應該使用snprintf接口。 **「** – mike 2015-05-21 17:37:28

9

一個環節有一個在2008年POSIX標準的一個非常整潔的功能:open_memstream()。您可以使用這樣的:

char* buffer = NULL; 
size_t bufferSize = 0; 
FILE* myStream = open_memstream(&buffer, &bufferSize); 

fprintf(myStream, "You can output anything to myStream, just as you can with stdout.\n"); 
myComplexPrintFunction(myStream); //Append something of completely unknown size. 

fclose(myStream); //This will set buffer and bufferSize. 
printf("I can do anything with the resulting string now. It is: \"%s\"\n", buffer); 
free(buffer); 
+1

有沒有'open_memstream'的好選擇?一些平臺(其中的solaris)不提供這個[尚]。 – 2015-08-04 22:41:39

+0

@BrianVandenberg最接近的是'asprintf()',這也不是所有平臺都提供的。所有其他的選擇都有嚴重的安全問題,因爲它們可以溢出所提供的緩衝區('sprintf()'和'fmemopen()'),或者強制你運行字符串生成兩次以避免在預分配的緩衝區太小時失敗的snprintf()')。只有'asprintf()'和'open_memstream()'提供安全的單通道語義。但是,如果'asprintf()'可以爲你工作,你可以通過'vsprintf()'兩遍來輕鬆實現你自己的版本。 – cmaster 2015-08-05 16:55:45

+0

謝謝你的迴應。我正在移植一個庫,我不是Solaris的維護者,它使用open_memstream相當數量,我希望找到一種方法來提供自定義版本以避免更改他們的代碼。我可能必須使用自定義的'write()/ close()'(當然調用libc版本)來使用庫插入。 – 2015-08-05 17:36:28