标准库函数strcpy,strncpy,strlcpy

C标准库函数strcpy,strncpy,strlcpy

#include<stdio.h>

snprintf(char* dest_str,size_t size,const char* format,…)

// 函数功能:先将可变参数 “…” 按照format的格式格式化为字符串,然后再将其拷贝至dest_str中。
// 注意:格式化后的字符串长度小于size,则全部拷贝,并在结尾添加'\0'。若大于等于size,则只拷贝size-1,并在结尾添加'\0'
int snprintf(char* dest_str,size_t size,const char* format,...);

char *s1 = "Linux C程序设计";  
int size = strlen(s1);  
int year = 2017;  
int month = 9;  
int day = 8;  
snprintf(dest_str,sizeof(dest_str),"字符串:%s\n长度是:%d\n今天是:%d年%d月%d日\n",s1,size,year,month,day);  
printf("%s",dest_str);

>>> 字符串:Linux C程序设计
    长度是:15
    今天是:201798// 实例

strcpy ,strncpy ,strlcpy的用法

strcpy ,strncpy ,strlcpy地用法
好多人已经知道利用strncpy替代strcpy来防止缓冲区越界。
但是如果还要考虑运行效率的话,也许strlcpy是一个更好的方式。

  1. strcpy

    我们知道,strcpy 是依据 ‘/0’ 作为结束判断的,如果 to 的空间不够,则会引起 buffer overflow。strcpy 常规的实现代码如下(来自 OpenBSD 3.9):

    char *strcpy(char *to, const char *from)
    {
        char *save = to;
        for (; (*to = *from) != '/0'; ++from, ++to);
        return(save);
    }

    但通常,我们的 from 都来源于用户的输入,很可能是非常大的一个字符串,因此 strcpy 不够安全。

  2. strncpy

    在 ANSI C 中,strcpy 的安全版本是 strncpy。
    char *strncpy(char *s1, const char *s2, size_t n)
    但 strncpy 其行为是很诡异的(不符合我们的通常习惯)。标准规定 n 并不是 sizeof(s1),而是要复制的 char 的个数。一个最常见的问题,就是 strncpy 并不帮你保证 '/0’结束。

    char buf[8];
    strncpy( buf, "abcdefgh", 8 );

    看这个程序,buf 将会被 “abcdefgh” 填满,但却没有 ‘/0’ 结束符了。
    另外,如果 s2 的内容比较少,而 n 又比较大的话,strncpy 将会把之间的空间都用 ‘/0’ 填充。这又出现了一个效率上的问题,如下:

    char buf[80];
    strncpy( buf, "abcdefgh", 79 );

    上面的 strncpy 会填写 79 个 char,而不仅仅是 “abcdefgh” 本身。
    strncpy 的标准用法为:(手工写上 /0)

    strncpy(path, src, sizeof(path) - 1);
    path[sizeof(path) - 1] = '/0';
    len = strlen(path);
  3. strlcpy

    size_t strlcpy(char *dst, const char *src, size_t siz);
    而使用 strlcpy,就不需要我们去手动负责 ‘/0’ 了,仅需要把 sizeof(dst) 告之 strlcpy 即可:

size_t Test_strlcpy(char *dest, const char *src, size_t size
{
	size_t ret = strlen(src);
	if (size) 
	{
		//这句判断大赞,起码有效防止源字符串的越界问题
		size_t len = (ret >= size) ? size - 1 : ret;
		memcpy(dest, src, len);
		dest[len] = '\0';
	}
		return ret;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值