我可以sprintf在我的应用程序中看到许多用于复制字符串的内容.
我有一个字符数组:
char myarray[10];
const char *str = "mystring";
Run Code Online (Sandbox Code Playgroud)
现在,如果我想要将字符串复制str到myarray,最好使用:
sprintf(myarray, "%s", str);
Run Code Online (Sandbox Code Playgroud)
要么
strncpy(myarray, str, 8);
Run Code Online (Sandbox Code Playgroud)
?
R..*_*R.. 39
根本不应该使用它们.
sprintf是危险的,被弃用的,被取代的snprintf.使用旧的sprintf安全字符串输入的唯一方法是在调用之前测量它们的长度sprintf,这是丑陋且容易出错的,或者通过添加字段精度说明符(例如,%.8s或者%.*s对于大小限制使用额外的整数参数).这也是丑陋且容易出错的,特别是如果%s涉及多个说明符.
strncpy也很危险 它不是缓冲区大小限制版本strcpy.它是将字符复制到固定长度,空填充(与空终止相对)数组的函数,其中源可以是C字符串或至少是目标大小的固定长度字符数组.它的用途是用于传统的unix目录表,数据库条目等,它们使用固定大小的文本字段,并且不想在磁盘或内存中浪费单个字节以进行空终止.它可能被误用为缓冲区大小限制strcpy,但这样做有害有两个原因.首先,如果整个缓冲区用于字符串数据(即源字符串长度至少与dest缓冲区一样长),则无法终止null.您可以自己添加终止,但这很难看并且容易出错.第二,strncpy当源字符串短于输出缓冲区时,始终使用空字节填充完整目标缓冲区.这只是浪费时间.
那么你应该用什么呢?
有些人喜欢BSD strlcpy功能.从语义上讲,它与snprintf(dest, destsize, "%s", source)返回值相同,size_t并且不会INT_MAX对字符串长度施加人为限制.但是,最流行的非BSD系统缺乏strlcpy,并且很容易编写自己的危险错误,因此如果您想使用它,您应该从可信赖的来源获得安全,已知的工作版本.
我的偏好是简单地snprintf用于任何非平凡的字符串构造,而strlen+ memcpy用于一些被测量为性能关键的琐碎案例.如果你养成了正确使用这个习惯用法的习惯,几乎不可能意外地编写带有字符串相关漏洞的代码.
| 归档时间: |
|
| 查看次数: |
27399 次 |
| 最近记录: |