所以情况很简单:我需要在c字符串前添加一个字符。
所以我有了我的代码:
char *a = "2233b";
char output[100];
char toAdd = '-';
strcpy(output, a);
printf("\noutput=%s", output);
sprintf(output, "%c%s", toAdd, a);
printf("\noutput=%s", output);
输出结果符合预期:
output=2233b
output=-2233b
好的,到目前为止一切顺利。现在情况发生了变化,我想在c字符串之前添加更多字符,所以我配置了代码:
char *a = "2233b";
char output[100];
char toAdd = '-';
strcpy(output, a);
printf("\noutput=%s", output);
sprintf(output, "%c%s", toAdd, a);
printf("\noutput=%s", output);
sprintf(output, "%c%s", toAdd, output);
printf("\noutput=%s", output);
我希望输出为:
output=2233b
output=-2233b
output=--2233b
但事实并非如此,我的屏幕上印有以下输出:
output=2233b
output=-2233b
output=-------
为什么output
包含此值?
因为格式只是字符(%c
)toAdd
('-'
)和字符串(%s
),output
并且包含("-2233b"
})。
那么为什么最后一个输出不包含"--2233b"
?为什么output
的字符都转换为'-'
?
答案 0 :(得分:3)
我认为问题出在
sprintf(output, "%c%s", toAdd, output);
在这里,您在一个有序的语句中读取和写入output
。这会调用undefined behaviour。
引用C11
,章节§7.21.6.6,sprintf()
函数
如果在重叠的对象之间进行复制,则行为未定义。
答案 1 :(得分:1)
这是调用未定义的行为,如* nix系统上的相应man
页面以及C
和POSIX
标准中所述。
NOTES
Some programs imprudently rely on code such as the following
sprintf(buf, "%s some further text", buf);
to append text to buf. However, the standards explicitly note that the
results are undefined if source and destination buffers overlap when call‐
ing sprintf(), snprintf(), 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.
The glibc implementation of the functions snprintf() and vsnprintf() con‐
forms to the C99 standard, that is, behaves as described above, since
glibc version 2.1. Until glibc 2.0.6, they would return -1 when the out‐
put was truncated.
答案 2 :(得分:1)
标准禁止传递对输入和输出重叠的缓冲区,因此行为未定义。
如果您有兴趣了解为什么会出现多个短划线,那么接下来会发生什么:问题是当您将output
作为输入传递给sprintf
时,这个函数的行为就像一条狗追逐自己的尾巴:它在读取它的第一个字符之前将第一个字符写入output
,然后在它尝试时将其写入“正面运行”其读取,但未成功处理%s
格式:新函数会在函数读取时添加到输出中。
要解决此问题,请在将output
传递给sprintf
之前制作一份var table = $('#example').dataTable( {
.....
table.fnUpdate(['x','y','z','4','X'], 0);
的临时副本。