智慧屏安装APP的最佳实践与跨平台小程序开发的结合
1544
2022-11-18
c语言strcat()/strcat_s()函数详解
前言
先看下strcat()/strcat_s()函数调用报错:
放大一点
严重性 代码 说明 项目 文件 行 禁止显示状态 错误 C4996 'strcat': This function or variable may be unsafe. Consider using strcat_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. openGLES3.0Example_6_MapBuffers D:\openGLESExercise\openGLES3.0Example_6_MapBuffers\MapBuffers.c 44
源码
void PrintLogMessage(const char* msg){ //GLint infoLen = GL_INFO_LOG_LENGTH; GLint infoLen = 512; char* infoLog = malloc(sizeof(char) * 512); glGetProgramInfoLog(programObject, infoLen, &infoLen, infoLog); GLint headLen = strlen("Invoke "); strcpy_s(infoLog, headLen+1, "Invoke "); //这里长度必须+1,要覆盖'\0',否则越界,vs2019边界检查更严格 /********* (1)src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。 /*********(2)strcat返回值有什么作用? 链式传递:strcat(a, strcat(b, c)); /********* 最重要的是,strcat函数不检查这些。*********/ strcat(infoLog, "Invoke "); //strcat_s(infoLog, msg, strlen(msg)+1); strcat_s(infoLog, strlen(msg) + 1, msg); esLogMessage(" failed:Error message:%s\n", infoLog); free(infoLog);}
strcat、strcpy、strcmp、strlen是C中针对字符串的库函数,这四个老式函数不安全,然后C标准库针对这个情况整出strcat_s、strcpy_s、strncmp、strnlen_s(这个并不是替代stelen的)来弥补。而在C++中一般用string。
下面主要讲:strcat()/strcat_s/strcpy()/strcpy_s()以及如何避免不安全的方法。
下面是我拷贝的大神文章:在加上我的一点理解吧
每天学一点!
/article/details/90598068
1 strcat 1.1 函数功能 把src所指字符串添加到dest结尾处(覆盖dest结尾处的'\0')并添加'\0'
#include
char *strcat(char *dest, const char *src)
参数:
dest -- 指向目标字符串,该数组包含了一个 C 字符串,且足够容纳追加后的字符串 src -- 指向要追加的字符串,该字符串不会覆盖目标的字符串
返回值:指向dest的指针
1.3 注意 (1)src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。最重要的是,strcat函数不检查这些。
(2)strcat返回值有什么作用? 链式传递:strcat(a, strcat(b, c));
1.4 strcat代码演示
#include "stdafx.h"#include
显示结果:
错误 1 error C4996: 'strcat': This function or variable may be unsafe. Consider using strcat_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
正如前言里说的,微软已经知道strcat等函数不安全了,直接不让你通过了,而解决措施也告诉我们了。但是这里为了先看看strcat,所以先不用strcat_s。
如何忽略这个警告/错误,措施有以下几种:
(1)第一种:_CRT_SECURE_NO_WARNINGS
VS中:项目 - 属性 - 配置 - C/C++ - 预处理器 - 预处理器定义里添加:_CRT_SECURE_NO_WARNINGS
(2)第二种: 加个预处理命令:#pragma warning(disable:4996)
这里注意:#pragma warning(disable:4996)要放在#include "stdafx.h"后面!(具体可以百度stdafx的用法)
#include "stdafx.h"#include
结果显示: str1 is Hello,world str2 is world 请按任意键继续. . . PS:这里如果要用strcat,我还是倾向于第二种方法,因为第一种方法久而久之我们自己给忘了,而第二种方法从程序里就能显而易见,从而提醒自己这是个不安全的函数。
前面也说,strcat函数有两个条件,dest的空间要能容纳src,且两者内存不能重叠。
下面分别看下不满足上述两个条件,会发生什么。
(1)dest空间不足
#include "stdafx.h"#include
从结果可以看出:当dest空间不足时,编译是可以通过的,但是在运行时出错。
(2)dest和src内存重叠
#include "stdafx.h"#include
结果:可以编译,但是无输出。
strcat小结:
不安全函数,全靠编程者自己注意。这种函数平常练习为了方便用用,真正写代码的时候还是不要用这种函数,东西多了脑子可能就忽视了。
1.5 针对strcat解决措施 (1)用strcat_s函数
errno_t strcat_s(char *strDestination, size_t numberOfElements, const char *strSource);
2 参数及返回值
参数:
strDestination -- 目标字符串缓冲区 numberOfElements -- 源字符串追加到目标字符串缓冲区后的总大小,单位字节
//注意!!!strcat_s()第二个参数的大小是 src+des+1总和大小,+1是字符串结尾符:'\0'的大小
strSource -- 源字符串缓冲区
返回值:
0:成功
EINVAL:目标字符串或者源字符串没有初始化
ERANGE:越界
3 注意
strcat_s函数从上面可以看出,做了两个检查,字符串有没有初始化和越界。并没有针对内存重叠做出检查。
第一个参数:合并字符串后的大小。即 源字符串大小 + 目标字符串的大小 + '\0'的大小 ,也就是
numberOfElements = strlen(strDestination) + strlen(strSource) + 1;
4 代码演示
#include "stdafx.h"#include
但是结果并不是:Dest's size is small!
调试的时候,发现rlt=0,而MSDN上著名返回值为0即成功。
这个地方我是真的百思不得其解啊!哪位大佬看到了这篇博客,有想法请一定告诉我! 谢谢!
(2)用C++的string函数
#include "stdafx.h"#include
输出结果: Hello,world 请按任意键继续. . . 用C++中的string类简单粗暴。
但是要注意以下几点
(1)当把string对象和字符字面值及字符串字面值混在一条语句中使用时,必须确保每个加法运算符的两侧的运算对象至少有一个是string。参考<
(2)string 怎么转 char* ?
char *str = const_cast
程序运行结果
工程源码-
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~