一文搞定C语言中的strcpy、strcat、sprintf以及其对应的各类其它版本

本文详细介绍了C语言中strcpy、strcat、sprintf等不安全函数的问题,以及它们的安全版本如strcpy_s、strcat_s、sprintf_s的优化之处。讨论了strncpy是否真正安全,并提醒程序员在使用时需要确保字符串长度和内存分配的合理性,以避免内存溢出和安全风险。

一文搞定C语言中的strcpy、strcat、sprintf以及其对应的各类其它版本


前言

在编写C语言程序时,若使用了strcpy、strcat、sprintf等函数,经常编译器会提醒该函数不安全,推荐使用更为安全的版本进行替换。这些函数为什么不安全?安全的版本又是如何实现的呢?本文将探讨这些问题。


一、先来看看有几类函数

  • strcpy、strcat、sprintf
  • strcpy_s、strcat_s、sprintf_s
  • strncpy、strncat、snprintf
  • strncpy_s、strncat_s、snprintf_s

先说明下,这些组函数只有名称带有 _s 后缀的才是安全的函数,但注意这些函数从C11版本中才支持,windows上的vs是默认支持这些函数的,这些函数也是先由ms在windows上实现的,并向c语言标准协会提出在标准中增加这些函数。在liunx下要使用这些函数,需要定义宏 STDC_LIB_EXT1 ,且在包含 string.h 前定义 STDC_WANT_LIB_EXT1 为整数常量 1 才保证可用。在Windows上VS2019编译器中__STDC_WANT_LIB_EXT1__宏默认定义为1,<string.h>头文件中包含了 _s 函数的声明,在Liunx系统下,使用gcc编译会失败,Linux / glibc维护者拒绝添加安全功能,认为您应该掌握字符串的长度并使用memcpy。

#define __STDC_WANT_LIB_EXT1__ 1
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
 
int main(void)
{
   
   
    char *src = "Take the test.";
	//src[0] = 'M' ; // 这会是未定义行为
    char dst[strlen(src) + 1]; // +1 以适应空终止符
    strcpy(dst, src);
    dst[0] = 'M'; // OK
    printf("src = %s\ndst = %s\n", src, dst);
 
#ifdef __STDC_LIB_EXT1__ //若不增加判断,并且未定义宏 __STDC_LIB_EXT1__ ,编译时会报错!
    set_constraint_handler_s(ignore_handler_s);
    int r = strcpy_s(dst, sizeof dst, src);
    printf("dst = \"%s\", r = %d\n", dst, r);
    r = strcpy_s(dst, sizeof dst, "Take even more tests."
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值