strncpy,snprintf,strnlen的用法

1,不使用strcpy和sprintf,它们可能导致缓冲区溢出

 

2,strncpy的用法

char *strncpy(char *dest, const char *src, size_t n);
标准用法:src串的长度应该小于dest缓冲区的大小,且n为dest缓冲区的大小减1或者更小,即至少留出一个位置给'\0'。(如果src串的长度大于或等于dest缓冲区的大小,则n应该为dest缓冲区的大小减1或者更小,否则将溢出。)

 

示例:

#include <stdio.h>
#include <string.h>

int main()
{
     char str1[5] = "";
     char str2[10] = "";
     char str3[15] = "";
    
     char* p = "0123456789";
     size_t np = 10;
    
//     strncpy(str1, p, sizeof(str1)); // 源串长度大于目标buf的大小,且拷贝个数等于目标buf的大小,溢出
//     printf("str1=%s/n", str1);
//    
//     strncpy(str1, p, np); // 源串长度大于目标buf的大小,且拷贝个数大于目标buf的大小,溢出
//     printf("str1=%s/n", str1);
    
     strncpy(str1, p, sizeof(str1) - 1); // 源串长度大于目标buf的大小,但是拷贝个数小于目标buf的大小,结果是拷贝了sizeof(str1)-1个字符,ok
     printf("str1=%s/n", str1);
    
//     strncpy(str2, p, sizeof(str2)); // 源串长度等于目标buf的大小,且拷贝个数等于目标buf的大小,溢出
//     printf("str2=%s/n", str2);
//    
//     strncpy(str2, p, np); // 源串长度等于目标buf的大小,且拷贝个数等于源串长度,溢出
//     printf("str2=%s/n", str2);

     strncpy(str2, p, sizeof(str2) - 1); // 源串长度等于目标buf的大小,但是拷贝个数小于目标buf的大小,结果是拷贝了sizeof(str2)-1个字符,ok
     printf("str2=%s/n", str2);
    
     strncpy(str3, p, sizeof(str3)); // 源串长度小于目标buf的大小,且拷贝个数等于目标buf的大小,ok,标准用法
     printf("str3=%s/n", str3);
    
     strncpy(str3, p, np); // 源串长度小于目标buf的大小,且拷贝个数等于源串长度,ok,非标准用法
     printf("str3=%s/n", str3);
    
     return 0;
}

// g++ t.cpp -o t -g -Wall
/*
str1=0123
str2=012345678
str3=0123456789
str3=0123456789
*/

 

3,snprintf的用法

int snprintf(char *str, size_t size, const char *format, ...);
说明: 最多从源串中拷贝(size - 1)个字符到目标串中,再在后面加一个'/0'。

返回值: 若成功则返回源串的长度,若出错则返回负值。

标准用法:源串长度应该小于目标str缓冲区的大小,且size等于目标str缓冲区的大小。(如果源串长度大于或等于目标str缓冲区的大小,且size等于目标str缓冲区的大小,则只会拷贝目标str缓冲区的大小减1个字符,后加'\0';该情况下,如果size大于目标str缓冲区的大小则溢出。)

 

示例:

#include <stdio.h>

int main()
{
 char str1[5] = "";
 char str2[10] = "";
 char str3[15] = "";
 
 char* p = "0123456789";
 size_t np = 10;
 int n;
 
 n = snprintf(str1, sizeof(str1), p); // 源串长度大于目标buf的大小,且拷贝个数等于目标buf的大小,只会拷贝sizeof(str1)-1个字符,后加'/0',ok,结果不是想要的
 printf("str1=%s, n=%d/n", str1, n);
 
 // n = snprintf(str1, np, p); // 源串长度大于目标buf的大小,且拷贝个数等于源串长度,溢出
 // printf("str1=%s, n=%d/n", str1, n);
 
 n = snprintf(str2, sizeof(str2), p); // 源串长度等于目标buf的大小,且拷贝个数等于目标buf的大小,只会拷贝sizeof(str2)-1个字符,后加'/0',ok,结果不是想要的
 printf("str2=%s, n=%d/n", str2, n);
 
 n = snprintf(str2, np, p); // 同上
 printf("str2=%s, n=%d/n", str2, n);
 
 n = snprintf(str2, 12, p); // 源串长度等于目标buf的大小,且拷贝个数大于目标buf的大小,只会拷贝整个源串,溢出
 printf("str2=%s, n=%d/n", str2, n);
 
 n = snprintf(str3, sizeof(str3), p); // 源串长度小于目标buf的大小,且拷贝个数等于目标buf的大小,会拷贝整个源串,后加'/0',ok,标准用法
 printf("str3=%s, n=%d/n", str3, n);
 
 n = snprintf(str3, np, p); // 源串长度小于目标buf的大小,且拷贝个数等于源串长度,只会拷贝np-1个字符,后加'/0',ok,结果不是想要的
 printf("str3=%s, n=%d/n", str3, n);
 
 return 0;
}


// g++ t.cpp -o t -g -Wall
/*
str1=0123, n=10
str2=012345678, n=10
str2=012345678, n=10
str2=0123456789, n=10
str3=0123456789, n=10
str3=012345678, n=10
*/

 

4,strnlen

size_t strnlen(const char *s, size_t maxlen);

说明:获取字符串s中的字符个数n,不包括结尾的'/0';如果n <= maxlen,则返回n,否则返回maxlen。

 

示例:

#include <stdio.h>
#include <string.h>

int main()
{
     char* p = "0123456789";
     size_t np = 10;
     size_t n;
    
     n = strnlen(p, 9);
     printf("n=%d/n", n);
    
     n = strnlen(p, np);
     printf("n=%d/n", n);
    
     n = strnlen(p, 11);
     printf("n=%d/n", n);
    
     return 0;
}

// g++ t.cpp -o t -g -Wall
/*
n=9
n=10
n=10
*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值