'strncpy'与'sprintf' [英] 'strncpy' vs. 'sprintf'

查看:167
本文介绍了'strncpy'与'sprintf'的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在应用程序中我可以看到很多sprintf用于复制字符串.

I can see many sprintf's used in my applications for copying a string.

我有一个字符数组:

char myarray[10];
const char *str = "mystring";

现在,如果我想将字符串str复制到myarray,最好使用:

Now if I want want to copy the string str into myarray, is is better to use:

sprintf(myarray, "%s", str);

strncpy(myarray, str, 8);

?

推荐答案

两者都不用.

  1. sprintf是危险的,已弃用并由snprintf取代.对字符串输入安全地使用旧的sprintf的唯一方法是在调用sprintf之前测量其长度,这很丑陋且容易出错,或者通过添加字段精度说明符(例如%.8s%.*s并带有一个额外的整数参数作为大小限制).这也很丑陋且容易出错,尤其是如果涉及到多个%s说明符时.

  1. sprintf is dangerous, deprecated, and superseded by snprintf. The only way to use the old sprintf safely with string inputs is to either measure their length before calling sprintf, which is ugly and error-prone, or by adding a field precision specifier (e.g. %.8s or %.*s with an extra integer argument for the size limit). This is also ugly and error-prone, especially if more than one %s specifier is involved.

strncpy也是危险的.它不是strcpy的受缓冲区大小限制的版本.这是一个将字符复制到固定长度的,以null- papped (与null- terminated 相反)数组中的函数,其中源可以是C字符串或固定长度的字符数组至少应为目标的大小.它的预期用途是用于固定大小的文本字段的旧版unix目录表,数据库条目等,甚至不想浪费磁盘或内存中的单个字节来进行空终止.可以将它 误用作缓冲区大小受限的strcpy,但是这样做有两个方面的危害.首先,如果整个缓冲区用于字符串数据(即,如果源字符串的长度至少与dest缓冲区一样长),则它不能使终止终止为空.您可以自己添加终端,但这很丑陋且容易出错.其次,当源字符串短于输出缓冲区时,strncpy总是用空字节填充整个目标缓冲区.这只是浪费时间.

strncpy is also dangerous. It is not a buffer-size-limited version of strcpy. It's a function for copying characters into a fixed-length, null-padded (as opposed to null-terminated) array, where the source may be either a C string or a fixed-length character array at least the size of the destination. Its intended use was for legacy unix directory tables, database entries, etc. that worked with fixed-size text fields and did not want to waste even a single byte on disk or in memory for null termination. It can be misused as a buffer-size-limited strcpy, but doing so is harmful for two reasons. First of all, it fails to null terminate if the whole buffer is used for string data (i.e. if the source string length is at least as long as the dest buffer). You can add the termination back yourself, but this is ugly and error-prone. And second, strncpy always pads the full destination buffer with null bytes when the source string is shorter than the output buffer. This is simply a waste of time.

那你应该怎么用呢?

有些人喜欢BSD strlcpy功能.从语义上讲,它与snprintf(dest, destsize, "%s", source)相同,除了返回值是size_t,并且不对字符串长度施加人为的INT_MAX限制.但是,大多数流行的非BSD系统都缺少strlcpy,并且编写自己的错误很容易造成危险,因此,如果要使用它,则应从可信赖的来源获得安全,可工作的版本.

Some people like the BSD strlcpy function. Semantically, it's identical to snprintf(dest, destsize, "%s", source) except that the return value is size_t and it does not impose an artificial INT_MAX limit on string length. However, most popular non-BSD systems lack strlcpy, and it's easy to make dangerous errors writing your own, so if you want to use it, you should obtain a safe, known-working version from a trustworthy source.

我的偏好是对于任何非平凡的字符串构造仅使用snprintf,对于已被认为对性能至关重要的一些平凡的情况,仅使用strlen + memcpy.如果您习惯于正确使用此习惯用法,那么几乎不可能意外地编写带有字符串相关漏洞的代码.

My preference is to simply use snprintf for any nontrivial string construction, and strlen+memcpy for some trivial cases that have been measured to be performance-critical. If you get in a habit of using this idiom correctly, it becomes almost impossible to accidentally write code with string-related vulnerabilities.

这篇关于'strncpy'与'sprintf'的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆