linux - 如何使用 snprintf 向一个数组中打印自己原有的内容和一些新的内容?
仅有的幸福
仅有的幸福 2017-05-27 17:44:46
0
1
779

snprintf这个函数是要指定长度,而且编译器会进行越界检查的,所以必须保证目标长度比所有参数加起来长。可是考虑以下程序:

#include  #include  #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,估计老一点版本的编译器不会报这个错误。

仅有的幸福
仅有的幸福

全部回复 (1)
洪涛

首先snprintf()的第二个参数代表的是缓冲区的大小,在这里应该是LENGTHsizeof(LENGTH)的值是4
(我猜你想写的应该是sizeof(cache)吧)。那么,改成snprintf(cache, LENGTH, "%s/ruaruarua", cache);之后就行了吗?我们看看这个例子:

#include  int main() { char buf[20] = "hello"; snprintf(buf, 20, "%s world", buf); puts(buf); return 0; }

这个例子企图给buf末尾添加一个字符串,看看输出

world

并没有达到期望的结果。这是为什么呢?snprintf()的手册里有这么一段:

Some programs imprudently rely on code such as the following

sprintf(buf, "%s some further text", buf);

to append text tobuf. However, the standards explicitly note that the results are undefined if source and destination buffers overlap when callingsprintf(),snprintf(),vsprintf(), andvsnprintf(). Depending on the version ofgcc(1). However, the standards explicitly note that the results are undefined if source and destination buffers overlap when callingsprintf(),

, vsprintf(), and vsnprintf(). Depending on the version of gcc(1)used, and the compiler options employed, calls such as the above will not produce the expected results.

printf()即如果原始和目标缓冲区重叠的话,这些

家族的函数执行结果将是未定义的。

snprintf()那该如何如何“向一个数组中打印自己原有的内容和一些新的内容”呢?一种方式是把传给

的缓冲区设为数组中字符串的末尾:

snprintf(buf + strlen(buf), 20, " world");
printf()那如何连续往缓冲区末尾添加数据呢?注意到家族的函数返回值都是打印的字符数(number of characters printed),那么可以这么调用:

#include  #include  int main() { char buf[40]; char *p = buf; p += sprintf(p, "hello %s\n", "world"); p += sprintf(p, "hello %s", "again"); /* and more similar calls... */ puts(buf); return 0; }
结果为
hello world hello again
    最新下载
    更多>
    网站特效
    网站源码
    网站素材
    前端模板
    关于我们 免责声明 Sitemap
    PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!