strcpy_s、sptintf_s与strcat_s是strcpy、sptintf与strcat的安全版本,均是通过指定缓冲区长度来避免存在的溢出风险。
strcpy_s 与strcpy
strcpy_s和strcpy函数的功能几乎是一样的。strcpy函数,就象gets函数一样,它没有方法来保证有效的缓冲区尺寸,所以它只能假定缓冲足够大来容纳要拷贝的字符串。在程序运行时,这将导致不可预料的行为。用strcpy_s就可以避免这些不可预料的行为。
这个函数用两个参数、三个参数都可以,只要可以保证缓冲区大小。
三个参数时:
errno_t strcpy_s(char *strDestination,size_t numberOfElements,const char *strSource);
两个参数时:
errno_t strcpy_s(char(&strDestination)[size],const char *strSource); // C++ only
例子:
#include<iostream>
#include<cstring>
using namespace std;void Test(void)
{char *str1 = NULL;str1 = new char[20];char str[7];strcpy_s(str1, 20, "hello world");//三个参数strcpy_s(str, "hello");//两个参数但如果:char *str=new char[7];会出错:提示不支持两个参数cout << "strlen(str1):" << strlen(str1) << endl << "strlen(str):" << strlen(str) << endl;printf(str1);printf("\n");cout << str << endl;
}int main()
{Test();return 0;
}
结果:
strlen(str1):11
strlen(str):5
hello world
hello
请按任意键继续. . .
sptintf_s与sptintf
sprintf
定义:
int sprintf( char *buffer, const char *format [, argument] ... );
常见用法
//把整数123 打印成一个字符串保存在s 中。
sprintf(s, "%d", 123); //产生"123"
可以指定宽度,不足的左边补空格:
sprintf(s, "%8d%8d", 123, 4567); //产生:" 123 4567"
当然也可以左对齐:
sprintf(s, "%-8d%8d", 123, 4567); //产生:"123 4567"
也可以按照16 进制打印:
sprintf(s, "%8x", 4567); //小写16 进制,宽度占8 个位置,右对齐
sprintf(s, "%-8X", 4568); //大写16 进制,宽度占8 个位置,左对齐
sprintf_s
int sprintf_s( char *buffer, size_t sizeOfBuffer, const char *format [, argument] ... );
#include<iostream>
#include<cstring>
using namespace std;int main()
{char filename[1024];//需要预先分配缓冲区char path1[128] = "D:\\Program\\Tesseract-OCR\\tesseract.exe";char path2[128] = "D:\\Program\\Tesseract-OCR\\";char path3[128] = "D:\\Program\\Tesseract-OCR\\txt";char path4[128] = "-l chi_sim";sprintf_s(filename,sizeof(filename), "%s %s %s %s", path1, path2, path3, path4);cout << filename;return 0;
}
strcat_s与strcat
原形: errno_t strcat_s(char *strDestination,size_t numberOfElements,constchar *strSource);
extern char *strcat(char *dest,char *src);
strDestination要为strSource留下足够的内存,具体为:
假设strDestination为一个数组的话,
sizeof(strDestination)>=sizeof(strSource)+strlen(strDestination);
numberOfElements=sizeof(strDestination)
举例说明二者的区别:
strcat_s(szBuf, 3, "kdfdfj"); // 第一种连接字符串方法
strcat(szBuf, "kdfdfj"); // 第二种连接字符串方法
对于这两个例句,你仔细看就会发现他们有缓冲区溢出的问题.
而用第一个函数则不同,它会抛出一个异常。
但使用第二个函数的结果则不能确定,因为它可能会错误地改变了程序中其他部分的内存的数据,有可能不会抛出异常,但 会导致程序数据错误,也可能由于非法内存访问抛出异常