#include <stdio.h> #include <stdarg.h> /* 该函数ret = min(size, 实际写入长度) - 1,即ret永远小于size * scnprintf(NULL, ...) -> segment err * scnprintf(str, 0, ...) -> -1 * scnprintf(str, 1, ...) -> 0 * scnprintf(str, size, "%s", NULL) <==> scnprintf(str, size, "%s", "(null)"); */ static inline int scnprintf(char *str, size_t size, const char *format, ...) { va_list ap; int len; va_start(ap, format); len = vsnprintf(str, size, format, ap); va_end(ap); if(len > -1 && len >= size) len = size - 1; return len; } int main(int argc, char **argv) { int write_len = 0, tmp_len; char argbuf[16] = {0}; /* for(int i = 1, left_len = sizeof(argbuf); i < argc; i++) if((tmp_len = scnprintf(argbuf + write_len, sizeof(argbuf) - write_len, "%s", argv[i])) > 0){ write_len += tmp_len; }else{ break; // 一般情况下,不会进入这里, 除非snprintf转换失败 } */ for(int i = 1, left_len = sizeof(argbuf); i < argc; i++) write_len += scnprintf(argbuf + write_len, sizeof(argbuf) - write_len, "%s", argv[i]); /* argv很长时,必有sizeof(argbuf) - write_len == 1, * 此时,下次调用scnprintf返回0,之后的argv[i]空转,不会再拼装任何字符到argbuf */ printf("write_len =%d, argbug=%s ", write_len, argbuf); return 0; }