sprintf与sprintf_s_c++ strcpy

sprintf与sprintf_s_c++ strcpy字符串拷贝函数strcpy, strcat, sprintf, strncpy, strncat和snprintf的区别对于strcpy,sprintf,strcat这些不安全的函数的讨论应该算是不少了,大家都知道可以用strn

字符串拷贝函数strcpy, strcat, sprintf, strncpy, strncat和snprintf的区别   对于strcpy,sprintf,strcat这些不安全的函数的讨论应该算是不少了,大家都知道可以用strncpy,snprintf和strncat来替换它们。但实际工作中似乎这些”安全版”的函数带来的疑惑还是不小,总结了一下,列在这里。   1.sprintf(char * str, const char * format, …) -> snprintf(char *   str, size_t size, const char * format, …)   vsprintf(char * str, const char * format, va_list ap) ->   vsnprintf(char * str, size_t size, const char * format, va_list ap)   按照C/C++标准,snprintf和vsnprintf永远不会往str中输出多于size所指定的字节数的字符(包括结尾的’0’),它们也保证了一定会在str中写入’0’,所以在使用这个函数后不用担心结尾的问题。   举例:   char buf[5];   snprintf(buf, 5, “This is a test string.”); // buf becomes “This”,   buf[4] is ‘0’ snprintf(buf, 6, “This is a test string.”); // ERROR:   buffer overflow snprintf(buf, 5, “abc”); // buf becomes “abc”, the   value of buf[3] is ‘0’, buf[4] is undefined.   然而,VC中的_snprintf函数并没有按照这样的规定来做,它在输出缓冲区不够大时就不会输出结尾的’0′(跟strncpy的行为类似)。所以要让上面的程序工作正常,必须做相应的修改。   char buf[5]; _snprintf(buf, 5, “This is a test string.”);// buf becomes   ”This “, buf[4] is ‘ ‘ buf[4] = 0; //   buf[4] is ‘0’ now. _snprintf(buf, 6, “This is a test string.”); //   ERROR: buffer overflow _snprintf(buf, 5, “abc”); // buf becomes “abc”,   the value of buf[3] is ‘0’, buf[4] is undefined.   如果要保证可移植性,就得按VC的写法,做一次对于标准来说很多余的”填0″的操作,再通过定义宏来区别平台分别选用snprintf或_snprintf。   2. strcat(char * dest, const char * src) -> strncat(char * dest,   const char * src, size_t n);   这个函数比较简单,它保证不会写入多于n+1个字符,并且保证最后一定以’0’结束。   举例:   char dest[5] = “abc”;   strncat(dest, “defghijklmn”, 5 – 3 – 1); // dest becomes “abcd”,   dest[4] is ‘0’, // always minus the buffer length by 1 as the value of   n. strncat(dest, “defghijklmn”, 5 – 3); // ERROR: buffer overflow   3. strcpy(char * dest, const char * src) -> strncpy(char * dest,   const char * src, size_t n);   strncpy是一个比较容易出错的函数,它保证复制src中不多于n字节的内容,但是如果src的前n个字节中没有包含’0’,就会导致   dest没有正常的以’0’终止。另外,它还保证如果src的长度小于n,则dest剩余的部分都会以’0’填充。在用这个函数时,有一个最佳实践就   是先把dest以0填充,并传入dest的长度减1的值作为n,这样可以确保安全。   举例:   char buf[5] = {0}; // Always zero-fill the buffer,   // always use this form to initialize the stack   arrays to get //better performance over memset.   char * buf2 = new char[5];   memset(buf2, 0, 5); // Always zero-fill the buffer   strncpy(buf, “abcde”, 5); // ERROR: buf is not null-terminated.   strncpy(buf2, “abcde”, 5 – 1); // Right, always minus the buffer   length by 1 //as the value of n. buf becomes “abcd”, buf[4]   //is ‘0’ by initilization;   // This is a common error in the existing code.   char buf3[5];   const char * str = “Test”;   strncpy(buf3, str, strlen(str)); // Wrong, buf may not   null-terminated, // potential buffer-overflow   strncpy(buf3, str, strlen(str)+1); // Wrong, potential   buffer-overflow. //No difference with using strcpy.   函数说明   char *strncpy(char *dest, const char *src, size_t n);   最多从src中拷贝n个字符到dest。如果src的大小小于n,那么dest剩下的部分将被填0;   如果src的大小大于等于n,那么dest剩下的部分不会被填0,于是dest将不会以0结束。   char *strncat(char *dest, const char *src, size_t n);   最多从源中拷贝n个字符到目标串中,并在后面加一个0;也就是说,最多会有n+1个字符被写进dest。如果dest的容量为n,那么将会dest将会溢出。   int snprintf(char *str, size_t size, const char *format, …);   最多从源串中拷贝size-1个字符到目标串中,然后再在后面加一个0。所以如果目标串的大小为size的话,将不会溢出。   所以,字符串拷贝,最好用snprintf。

2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/85639.html

(0)
上一篇 2024年 7月 27日 上午8:08
下一篇 2024年 7月 27日

相关推荐

关注微信