简体   繁体   English

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

[英]best method to assign new string value to char array

I know that I have to use strcpy / strncpy to assign a new string value to an existing char array.我知道我必须使用 strcpy / strncpy 为现有的 char 数组分配一个新的字符串值。 Recently I saw a lot of code like this最近看到很多这样的代码

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

Both variants give the same result.两种变体给出相同的结果。 What is the advantage of the latter variant?后一种变体的优点是什么?

It depends on whether the string to be copied is a literal, as shown, or can vary.这取决于要复制的字符串是文字(如图所示)还是可以变化。

The best technique for the array shown would be:所示阵列的最佳技术是:

char arr[128] = "Hello World";

If you're in charge of the string and it contains no % symbols, then there's not much difference between the two sprintf() calls.如果您负责字符串并且它不包含%符号,那么两个sprintf()调用之间没有太大区别。 Strictly, the first uses the string as the format and copies the characters directly, while the second notes it has %s as the format and copies the characters from the extra argument directly — it's immeasurably slower.严格来说,第一个使用字符串作为格式并直接复制字符,而第二个注意到它以%s作为格式并直接从额外参数复制字符 - 它的速度要慢得多。 There's a case for:有一个案例:

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

which ensures no buffer overflow even if "Hello World" becomes a much longer diatribe.这确保即使“Hello World”成为更长的谩骂也不会发生缓冲区溢出。

If you're not in charge of the string, then using snprintf() as shown becomes important as even if the string contains % symbols, it is simply copied and there's no overflow.如果您不负责字符串,那么如图所示使用snprintf()变得很重要,因为即使字符串包含%符号,它也会被简单地复制并且没有溢出。 You have to check the return value to establish whether any data was truncated.您必须检查返回值以确定是否有任何数据被截断。

Using strcpy() is reasonable if you know how long the string is and that there's space to hold it.如果您知道字符串有多长并且有空间容纳它,则使用strcpy()是合理的。 Using strncpy() is fraught — it null pads to full length if the source is shorter than the target, and doesn't null terminate if the source is too long for the target.使用strncpy()很麻烦——如果源比目标短,它会空填充到全长,如果源对于目标来说太长,它不会空终止。

If you've established the length of the string is short enough, using memmove() or memcpy() is reasonable too.如果您已经确定字符串的长度足够短,那么使用memmove()memcpy()也是合理的。 If the string is too long, you have to choose an error handling strategy — truncation or error.如果字符串太长,则必须选择错误处理策略——截断或错误。

If the trailing (unused) space in the target array must be null bytes (for security reasons, to ensure there's no leftover password hidden in it), then using strncpy() may be sensible — but beware of ensuring null termination if the source is too long.如果目标数组中的尾随(未使用)空间必须是空字节(出于安全原因,以确保其中没有隐藏剩余密码),那么使用strncpy()可能是明智的——但要注意确保空终止,如果源是太长。 In most cases, the initializer for the array is not really needed.在大多数情况下,实际上并不需要数组的初始化程序。

The compiler may be able to optimize the simple cases.编译器可能能够优化简单的情况。

The first version won't work if the string contains any % characters, because sprintf() will treat them as formatting operators that need to be filled in using additional arguments.. This isn't a problem with a fixed string like Hello World , but if you're getting the string dynamically it could cause undefined behavior because there won't be any arguments to match the formatting operators.如果字符串包含任何%字符,第一个版本将不起作用,因为sprintf()会将它们视为需要使用其他参数填充的格式化运算符。这对于像Hello World这样的固定字符串不是问题,但是如果您动态获取字符串,则可能会导致未定义的行为,因为不会有任何参数来匹配格式化运算符。 This can potentially cause security exploits.这可能会导致安全漏洞。

If you're not actually doing any formatting, a better way is to just use strcpy() :如果您实际上没有进行任何格式化,更好的方法是使用strcpy()

strcpy(arr, "Hello World");

Also, when initiallizing the string it's not necessary to put an explicit \\0 in the string.此外,在初始化字符串时,没有必要在字符串中放置一个明确的\\0 A string literal always ends with a null byte.字符串文字总是以空字节结尾。 So you can initialize it as:所以你可以将它初始化为:

char arr[128] = "";

And if you're immediately overwriting the variable with sprintf() or strcpy() , you don't need to initialize it in the first place.如果您立即使用sprintf()strcpy()覆盖变量,则无需首先对其进行初始化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM