C++ sprintf 删除未定义的行为

c++ sprintf remove undefined behavior

我知道,像这样的东西

char a[1024] = "Hello";
char b[6] = "World";

sprintf(a, "%s %s", a, b);

导致未定义的行为。我知道,我可以使用 strcat 等其他函数,但是如果我想使用 sprintf 函数(我知道我可以在数组边界上写的风险),如果我写了一些东西,我可以删除未定义的行为吗像这样

sprintf(a + strlen(a), "%s %s", a, b)

还是它仍然未定义,我必须使用一个临时变量?

could I remove the undefined behavior if I write something like this

sprintf(a + strlen(a), "%s", b)

or is it still undefined and I have to use a temporary variable?

是的,你可以。不,它不会仍然是 UB。


编辑:

could I remove the undefined behavior if I write something like this

sprintf(a + strlen(a), "%s %s", a, b)

or is it still undefined and I have to use a temporary variable?

不,你不能。它仍然是 UB,因为您仍然写入作为参数传递的字符串。

你说得对

sprintf(a, "%s %s", a, b);

会导致 undefined behavior,因为源字符串和目标字符串重叠。

但是,行

sprintf(a + strlen(a), "%s %s", a, b);

仍然会导致未定义的行为,因为 a + strlen(a) 是字符串 a 的终止空字符的地址(这意味着源字符串 a 和目标字符串 a + strlen(a) 仍然重叠)。如果字符串不应重叠,则该行必须更改为以下内容:

sprintf(a + strlen(a) + 1, "%s %s", a, b);

由于不再有任何重叠,该行不会导致未定义的行为。

如果你希望能够将内存从一个内存缓冲区复制到另一个与第一个内存缓冲区重叠的内存缓冲区,那么我推荐使用函数memmove. In contrast to memcpy,函数memmove允许重叠内存缓冲区,其行为就像内容先写入临时缓冲区,然后再写入目标缓冲区。因此,即使缓冲区重叠,该函数的行为也不是未定义的,而是明确定义的。不幸的是,字符串没有等效的函数 strmove