我这样使用snprintf以避免缓冲区溢出:
char err_msg[32] = {0};
snprintf(err_msg, sizeof(err_msg) - 1, "[ ST_ENGINE_FAILED ]");
Run Code Online (Sandbox Code Playgroud)
-1如果字符串长度超过32个字节,我为null终止符添加了保留空间.
我的想法是否正确?
平台:
D.S*_*ley 28
正如其他人所说,在这种情况下你不需要-1.如果数组是固定大小,我会strncpy改为使用.它是为复制字符串sprintf而制作的- 是为了进行难以格式化而制作的.但是,如果数组的大小未知或您正在尝试确定格式化字符串需要多少存储空间.这是我真正喜欢标准指定版本的snprintf:
char* get_error_message(char const *msg) {
size_t needed = snprintf(NULL, 0, "%s: %s (%d)", msg, strerror(errno), errno);
char *buffer = malloc(needed+1);
sprintf(buffer, "%s: %s (%d)", msg, strerror(errno), errno);
return buffer;
}
Run Code Online (Sandbox Code Playgroud)
结合此功能,va_copy您可以创建非常安全的格式化字符串操作.
不需要-1.C99 snprintf 始终为零终止.Size参数指定输出缓冲区的大小,包括零终止符.因此,代码变为
char err_msg[32];
int ret = snprintf(err_msg, sizeof err_msg, "[ ST_ENGINE_FAILED ]");
Run Code Online (Sandbox Code Playgroud)
ret包含打印的实际字符数(不包括零终结符).
但是,不要与微软的混淆_snprintf(预C99),这确实不是空终止,并且,对于这个问题,有完全不同的行为(例如返回-1,而不是想成为印刷长度的情况下,如果缓冲区不够大).如果使用_snprintf,您应该使用与问题相同的代码.