簡體   English   中英

通過snprintf在C中填充靜態字符串緩沖區

[英]Populating static string buffer in C via snprintf

我有一些緩沖區並且知道大小

#define BUFFER_SIZE 1024*1024
char buffer[BUFFER_SIZE];

我必須用一些復雜的字符串填充此緩沖區。

int populate_string(char *buffer) {
    char *tbuffer = buffer;
    size_t tsize = BUFFER_SIZE;
    int rv;

    rv = snprintf(tbuffer, tsize, "foobar %s %d %s %D", ...);
    if (rv < 0) {
        printf("snprintf() error");
        return -1;
    } else if (rv >= tsize) {
        printf("overflow, increase buffer size");
        return -1;
    } else {
        tsize -= rv;
        tbuffer += rv;
    }

    // repeat snprintf's until string is fully populated

    return 0;
}

因此,我有三個問題:

  1. 這是動態填充靜態字符串的最佳方法嗎?
  2. 我填充字符串的方式安全嗎?
  3. 如何減少行數? 這些返回值檢查占據很多位置,尤其是在有很多snprintfs的情況下。
  1. 然后,取決於您對該字符串的處理方式:)顯而易見的替代方法是使用鏈接列表。
  2. 是的,這很安全。
  3. 有時無需檢查它是否為snprintf錯誤或溢出-因此您只能使用一個if()檢查。

您可能會對open_memstream和fmemopen感興趣:

http://linux.die.net/man/3/open_memstream

您可以通過打開緩沖區中的文件流來填充緩沖區,即:

FILE *f=fmemopen(buffer,BUFFER_SIZE,"w");
fwrite(f,...); 

當您達到“緩沖區”的上限時,寫入此流將產生一個錯誤(如果禁用緩沖)。

另外,您可以使用open_memstream在內存中創建一個流,該流將自動調整大小以保存您寫入的內容。

假設您使用的緩沖區長度正確,則使用snprintf應該是安全的。 如果緩沖區長度減少,則會遇到問題。 而不是使用tsize來存儲緩沖區的長度,而是讓調用者將緩沖區長度作為參數傳遞。 那應該使您的函數可重復用於不同的緩沖區大小。 您仍然必須相信調用方提供的值是准確的,但是我想您不能完全對該函數進行防錯。

如果要減少行數,請將多個snprintf調用合並為一個。 這將減少所需的錯誤檢查塊的數量。 缺點是您可能會在字符串中途耗盡緩沖區,但我認為您當前的代碼也無法避免這種情況。 為此,您必須打印到臨時的內部字符串,測量該字符串的長度,然后在且僅當剩余空間足夠時將其復制到輸出緩沖區。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM