snprintf
這個函數是要指定長度,而且編譯器會進行越界檢查的,所以必須保證目標長度比所有參數加起來長。可是考慮以下程序:
#include <stdio.h>
#include <string.h>
#define LENGTH 1024
int main() {
char cache[LENGTH];
memset(cache, 0, LENGTH);
snprintf(cache, sizeof(LENGTH), "%s/ruaruarua", cache);
return 0;
}
這個程式開了-Wall
之後會報錯:
test.c: In function ‘main’:
test.c:9:44: error: ‘/ruaruarua’ directive output truncated writing 10 bytes into a region of size 4 [-Werror=format-truncation=]
snprintf(cache, sizeof(LENGTH), "%s/ruaruarua", cache);
~~~~^~~~~~
test.c:9:5: note: ‘snprintf’ output 11 or more bytes into a destination of size 4
snprintf(cache, sizeof(LENGTH), "%s/ruaruarua", cache);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
這個錯誤是符合預期的,因為確實有可能越界。那麼問題來了,我怎麼能完成同樣的功能但是不報錯呢?
我的gcc
版本比較新,7.1.1
,估計老一點版本的編譯器不會報這個錯誤。
首先
snprintf()
的第二個參數代表的是緩衝區的大小,在這裡應該是LENGTH
,sizeof(LENGTH)
的值是4(我猜你想寫的應該是
size (cache)
吧)。那麼,改成snprintf(cache, LENGTH, "%s/ruaruarua", cache);
之後就行了嗎?我們來看看這個例子:這個範例企圖給
buf
末尾加上一個字串,看看輸出並沒有達到期望的結果。這是為什麼呢?
的緩衝區設為數組中字串的結尾:snprintf()
的手冊裡有這麼一段:那如何連續往緩衝區末端新增資料呢?注意到
printf()家族的函數回傳值都是列印的字元數(number of characters printed),那麼可以這麼呼叫:結果為