一文搞定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."

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





