将新字符串值分配给 char 数组的最佳方法

best method to assign new string value to char array

我知道我必须使用 strcpy / strncpy 将新的字符串值分配给现有的 char 数组。最近看到很多这样的代码

char arr[128] = "[=10=]";
sprintf(arr, "Hello World"); // only string constants no variable input
// or
sprintf(arr, "%s", "Hello World");

两种变体给出相同的结果。后一种变体的优点是什么?

如果字符串包含任何 % 个字符,第一个版本将不起作用,因为 sprintf() 会将它们视为需要使用其他参数填充的格式化运算符。这不是'像 Hello World 这样的固定字符串没有问题,但是如果您动态获取字符串,它可能会导致未定义的行为,因为不会有任何参数来匹配格式化运算符。这可能会导致安全漏洞。

如果您实际上没有进行任何格式化,更好的方法是只使用 strcpy():

strcpy(arr, "Hello World");

此外,在初始化字符串时,不必在字符串中显式放置 [=16=]。字符串文字总是以空字节结尾。所以你可以将它初始化为:

char arr[128] = "";

如果您立即用 sprintf()strcpy() 覆盖变量,则无需首先对其进行初始化。

这取决于要复制的字符串是否是文字,如图所示,或者可以变化。

所示阵列的最佳技术是:

char arr[128] = "Hello World";

如果您负责字符串并且它不包含 % 符号,那么这两个 sprintf() 调用之间没有太大区别。严格来说,第一个使用字符串作为格式并直接复制字符,而第二个注意它具有 %s 作为格式并直接从额外参数复制字符——它慢得无法估量。有一个案例:

snprintf(arr, sizeof(arr), "%s", "Hello World");

即使 "Hello World" 变得更长的谩骂也能确保缓冲区不会溢出。

如果您不负责字符串,那么使用 snprintf() 变得很重要,因为即使字符串包含 % 符号,它也只是被复制并且没有溢出。您必须检查 return 值以确定是否有任何数据被截断。

如果您知道字符串的长度并且有 space 来保存它,那么使用 strcpy() 是合理的。使用 strncpy() 很麻烦——如果源比目标短,它会空填充到全长,如果源对于目标来说太长,它不会空终止。

如果您确定字符串的长度足够短,使用 memmove()memcpy() 也是合理的。如果字符串太长,则必须选择一种错误处理策略——截断或错误。

如果目标数组中的尾随(未使用)space 必须为空字节(出于安全原因,以确保其中没有隐藏剩余的密码),那么使用 strncpy() 可能是明智的— 但要注意确保如果源代码太长则空终止。在大多数情况下,实际上并不需要数组的初始化程序。

编译器也许能够优化简单的情况。