001_安全函数_C_safe_library

关于操作字符串的安全函数,这些并非是C标准中的,是微软实现的,所以可能你在没有引入实现的情况下去运用,就会提示没有发现此定义类似提示,如下:

所以要把实现的函数引入,再用,如下:

 将实现函数及头文件引入,然后进行使用,下面我们开始:

【函数1: memset_s】

【格式】

memset_s(dest, sizeof(dest), int n, sizeof(dest))

【功能】

初始化某一块指定长度(一般情况下为字符数组)的内存为n值,或者理解为:初始化内存内容为某一数值,也可以的

【入参】

dest:内存块地址
sizeof(dest):内存块总大小
n:要被初始化的值,一般情况下是0
sizeof(dest):要被初始化的内存长度

【返回值】

这里我们对这个返回值一般不关心,因为我们主要是初始化内存块,获得返回值对于我们来说也并没有什么太大的用,是作为返回给系统进行校验的,这个有兴趣的可以去查询下关于size_t,errno_t, rsize_t类型的定义和含义,我们这里主要介绍函数功能和使用

【test_code】

 【总结】

这个memset_s函数比我们的void * memset(void *s, int c, size_t n);函数多了一个内存总长度的入参,在初始化时候,编译器会检验是否超过内存总长度,所以相对而言比较安全

【函数2: strncpy_s】

【格式】

char* strncpy_s(char *dest, sizeof(dest),char *src, strlen(src));

【功能】

向目的内存拷贝一定长度的字符串

【入参】

dest:目的地址
sizeof(dest):可拷贝大小
src:待拷贝的字符串
strlen(src):待拷贝的字符串有效长度

【test_code】

 【总结】

我们可以看下:

char *strcpy(char *dest, const char *src);

char *strncpy(char *dest, const char *src, int n);

char* strncpy_s(char *dest, sizeof(dest),char *src, strlen(src));

会发现其实后来的cp函数比原来的在长度和安全区做了更多的限定,所以才"安全"!

【函数3: strcat_s】

【格式】

errno_t strcat_s(char *strDest, size_t destMax, const char *strSrc);

【功能】

在一个字符串后面追加上另外一个字符串

【入参】

strDest:目的地址
destMax:目的地址最大容量
char:待操作的字符串

【返回值】

返回一个整数,0表示复制成功,返回非0值代表复制不成功,不同的值表示不同的错误,具体内容可以查阅MSDN手册

【test_code】

输出结果:

【总结】

 char *strcat(char *dest, const char *src);

char *strncat(char *dest, const char *src, size_t n);

 errno_t strcat_s(char *strDest, size_t destMax, const char *strSrc);

可以看出多了一个参数,长度限定

#include <stdio.h>
#include <string.h>
#include "./head/log.h"


int main()
{
        char src[MAXS] = "I am okay!";
        char dest[MAXS];
        char *p = "hello";

        memset(dest, 0, sizeof(dest));
        //dest[MAXS] = "hello";只有在初始化时才可以这样赋值,后面只能用copy函数赋值
        strncpy(dest, p, sizeof(char)*6);
        LOGS(dest);
        LOG();
        strcat(dest, src);
        LOGS(dest);

        strncat(dest, src, sizeof(char)*10);
        LOG();
        LOGS(dest);
        return SUCCESS;
}
输出:
hello
===============
helloI am okay!
===============
helloI am okay!I am okay!

/*strcat_s验证*/
void cats()
{
    char dest[200] = "I am ...";
    char src[] = "hello day";

    LOGS(dest);//I am ...
    strcat_s(dest, sizeof(dest), src);
    LOG();
    LOGS(dest);//I am ...hello day
}
int main()
{
    char dest[MAXS];
    char *str = "it is not a good idea in life!";


    memset_s(dest, sizeof(dest), 0, sizeof(dest));
    LOGS("str", str);
    LOGS("dest", dest);
    LOG();
    strcat(dest, str);
    LOGS("strcat_dest", dest);
    memset(dest, 0, sizeof(dest));
    strcat_s(dest, sizeof(dest), str);
    LOG();
    LOGS("strcat_s__dest", dest);

    return SUCCESS;
}

【函数4: memcpy_s】

【格式】

errno_t memcpy_s(char *dest , size_t big , const char *src , size_t count);

【功能】

拷贝一定长度的字符串到目的内存dest

【入参】

dest:拷贝完成之后的字符串地址
big: dest的大小,一般都是sizeof(dest)
src:需要拷贝的字符串
count:需要拷贝的字符串长度

注意:big必须大于等于count,否则拷贝将出现中断。

【返回值】

返回一个整数,0表示复制成功,返回非0值代表复制不成功,不同的值表示不同的错误,具体内容可以查阅MSDN手册

【test_code】

 【总结】

void *memcpy(void *destin, void *source, unsigned n);

errno_t memcpy_s(char *dest , size_t big , const char *src , size_t count);

还是多了个范围限定

【函数4: sscanf_s】

【格式】

int sscanf(const char *str, const char *format, ...);

int sscanf_s(const char *buffer, const char *format, ...)

【功能】

将字符或者数值赋予某个变量,这只是简单的一种用法而已

【入参】

buffer:原始数据
format:不定参数,以某种格式去把原始数据操作存储或者赋予新变量中,以备使用

【返回值】

整形,一般不用来做检验,没多大意义

【test_code】

char input[] = "42";
int number;
sscanf_s(input, "%d", &number, sizeof(number));

char input[] = "42";
int number;
sscanf(input, "%d", &number);

【总结】

可以看出sscanf_s比sscanf多了一个sizeof校验参数,对于操作的变量,所以更安全了哦

【函数4: snprintf_s

【格式】

int snprintf(char *str, size_t size, const char *format, ...);

int snprintf_s(char *str, size_t size, size_t size-1, const char *format, ...);

【功能】

将字符串和数值组合成一个命令

【入参】

str:待操作的地址块
size:待操作的地址块的大小
size-1:允许被操作的地址块大小
format:不定参数,以某种格式去把数据赋值给地址块

【返回值】

整形,可以用了做检验,均可

#include <stdio.h>

int main() {
    char buffer[20];
    int num = 42;

    // Format the data into the buffer
    int num_chars_written = snprintf(buffer, sizeof(buffer), "The number is %d", num);

    // Check if the operation was successful and print the result
    if (num_chars_written < sizeof(buffer)) {
        printf("Formatted string: %s\n", buffer);
    } else {
        printf("Buffer size too small to store the formatted string.\n");
    }

    return 0;
}

【test_code】

char buffer[20];
    int num = 42;

    // Format the data into the buffer
    int num_chars_written = snprintf(buffer, sizeof(buffer), "The number is %d", num);

snprintf_s(buffer, sizeof(buffer), sizeof(buffer) - 1, "The number is %d", num);

【总结】

可以看出snprintf_s比snprintf多了一个sizeof校验参数,对于操作的变量,所以更安全了哦

【函数5: fscnaf_s】

这个函数目前用的不多,所以就没有举例演示

【注意】

我们这里用到了多个文件编译,所以需要用Makefile,如下:

这里关于这个不做赘述,我的主页有关于这个的文章,大家有兴趣的可以去看下,就知道怎么会回事了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值