日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

关于sprintf和snprintf的比较

發(fā)布時(shí)間:2023/12/9 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 关于sprintf和snprintf的比较 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
#include <stdio.h> #include <string.h>typedef unsigned char uchar;#define BUF_SIZE 10 // 緩沖區(qū)大小 #define CLEAR_SIZE (BUF_SIZE+2) // 操作的緩沖區(qū)大小, 需要全部重置void printRuler(int len) {putchar('\n');for(int i = 1; i <= len; i++){printf("%02d ", i);if(i == BUF_SIZE)printf("\t|\t");}putchar('\n'); }void dis(char *buf, int len) {for(int i = 0; i < len; i++){printf("%02x ", (uchar)buf[i]);if(i == BUF_SIZE - 1)printf("\t|\t");} // puts("\n"); // 另起一行輸出字符串并換行, 不會(huì)接在原來的后面putchar('\n'); // 直接輸出字符printf("buf=[%s]\n\n", buf); }int main() {char buf[BUF_SIZE];memset(buf, 0xcc, CLEAR_SIZE);dis(buf, CLEAR_SIZE);printRuler(CLEAR_SIZE);printf("-------------------------------------- snprintf\n");memset(buf, 0xcc, CLEAR_SIZE);snprintf(buf, BUF_SIZE, "%s", "12345678"); // 未溢出dis(buf, CLEAR_SIZE);memset(buf, 0xcc, CLEAR_SIZE);snprintf(buf, BUF_SIZE, "%s", "123456789"); // 未溢出, 剛好填滿dis(buf, CLEAR_SIZE);memset(buf, 0xcc, CLEAR_SIZE);snprintf(buf, BUF_SIZE, "%s", "123456789A"); // 未溢出, 被截?cái)?個(gè)字符dis(buf, CLEAR_SIZE);memset(buf, 0xcc, CLEAR_SIZE);snprintf(buf, BUF_SIZE, "%s", "123456789AB"); // 未溢出, 被截?cái)?個(gè)字符dis(buf, CLEAR_SIZE);//printRuler(CLEAR_SIZE);printf("-------------------------------------- sprintf\n");memset(buf, 0xcc, CLEAR_SIZE);sprintf(buf, "%s", "12345678"); // 未溢出dis(buf, CLEAR_SIZE);memset(buf, 0xcc, CLEAR_SIZE);sprintf(buf, "%s", "123456789"); // 剛剛好dis(buf, CLEAR_SIZE);memset(buf, 0xcc, CLEAR_SIZE);sprintf(buf, "%s", "123456789A"); // 溢出1個(gè)字符dis(buf, CLEAR_SIZE);memset(buf, 0xcc, CLEAR_SIZE);sprintf(buf, "%s", "123456789AB"); // 溢出2個(gè)字符dis(buf, CLEAR_SIZE);return 0; }/*運(yùn)行情況: D:\profile\Desktop\test>make g++ -o a.exe a.cppD:\profile\Desktop\test>a cc cc cc cc cc cc cc cc cc cc | cc cc buf=[燙燙燙燙燙燙@]01 02 03 04 05 06 07 08 09 10 | 11 12 -------------------------------------- snprintf 31 32 33 34 35 36 37 38 00 cc | cc cc buf=[12345678]31 32 33 34 35 36 37 38 39 00 | cc cc buf=[123456789]31 32 33 34 35 36 37 38 39 00 | cc cc buf=[123456789]31 32 33 34 35 36 37 38 39 00 | cc cc buf=[123456789]01 02 03 04 05 06 07 08 09 10 | 11 12 -------------------------------------- sprintf 31 32 33 34 35 36 37 38 00 cc | cc cc // 空間有余 buf=[12345678]31 32 33 34 35 36 37 38 39 00 | cc cc // 剛好填充満 buf=[123456789] 31 32 33 34 35 36 37 38 39 41 | 00 cc // 溢出1個(gè)字符 buf=[123456789A]31 32 33 34 35 36 37 38 39 41 | 42 00 // 溢出2字符 buf=[123456789AB]結(jié)論:1. sprintf和snprintf都會(huì)在字符串末尾加上'\0'2. snprintf比sprintf安全,即不會(huì)造成緩沖區(qū)溢出 */

以上的測(cè)試環(huán)境是GNUMake(windows), 和Linux.


===============================================================================

以下的代碼測(cè)試環(huán)境是windows vc6和vc2010

#define _CRT_SECURE_NO_WARNINGS // 針對(duì)vc2010添加#include <stdio.h> #include <string.h>typedef unsigned char uchar;#ifdef WIN32#define snprintf _snprintf // windows平臺(tái)無(wú)snprintf, 但是有_snprintf #endif#define BUF_SIZE 10 // 緩沖區(qū)大小 #define CLEAR_SIZE (BUF_SIZE+2) // 操作的緩沖區(qū)大小, 需要全部重置void printRuler(int len) {putchar('\n');for(int i = 1; i <= len; i++){printf("%02d ", i);if(i == BUF_SIZE)printf("\t|\t");}putchar('\n'); }void dis(char *buf, int len) {for(int i = 0; i < len; i++){printf("%02x ", (uchar)buf[i]);if(i == BUF_SIZE - 1)printf("\t|\t");} // puts("\n"); // 另起一行輸出字符串并換行, 不會(huì)接在原來的后面putchar('\n'); // 直接輸出字符printf("buf=[%s]\n\n", buf); }int main() {char buf[BUF_SIZE];memset(buf, 0xcc, CLEAR_SIZE);dis(buf, CLEAR_SIZE);printRuler(CLEAR_SIZE);printf("-------------------------------------- snprintf\n");memset(buf, 0xcc, CLEAR_SIZE);snprintf(buf, BUF_SIZE, "%s", "12345678"); // 未溢出dis(buf, CLEAR_SIZE);memset(buf, 0xcc, CLEAR_SIZE);snprintf(buf, BUF_SIZE, "%s", "123456789"); // 未溢出, 剛好填滿dis(buf, CLEAR_SIZE);memset(buf, 0xcc, CLEAR_SIZE);snprintf(buf, BUF_SIZE, "%s", "123456789A"); // 未溢出, 被截?cái)?個(gè)字符dis(buf, CLEAR_SIZE);memset(buf, 0xcc, CLEAR_SIZE);snprintf(buf, BUF_SIZE, "%s", "123456789AB"); // 未溢出, 被截?cái)?個(gè)字符dis(buf, CLEAR_SIZE);//printRuler(CLEAR_SIZE);printf("-------------------------------------- sprintf\n");memset(buf, 0xcc, CLEAR_SIZE);sprintf(buf, "%s", "12345678"); // 未溢出dis(buf, CLEAR_SIZE);memset(buf, 0xcc, CLEAR_SIZE);sprintf(buf, "%s", "123456789"); // 剛剛好dis(buf, CLEAR_SIZE);memset(buf, 0xcc, CLEAR_SIZE);sprintf(buf, "%s", "123456789A"); // 溢出1個(gè)字符dis(buf, CLEAR_SIZE);memset(buf, 0xcc, CLEAR_SIZE);sprintf(buf, "%s", "123456789AB"); // 溢出2個(gè)字符dis(buf, CLEAR_SIZE);return 0; }/*運(yùn)行情況(vc6/vc2010):cc cc cc cc cc cc cc cc cc cc | cc ccbuf=[燙燙燙燙燙燙?]01 02 03 04 05 06 07 08 09 10 | 11 12-------------------------------------- snprintf31 32 33 34 35 36 37 38 00 cc | cc cc // 未溢出時(shí)會(huì)填充字符串結(jié)束符('\0')buf=[12345678]31 32 33 34 35 36 37 38 39 00 | cc cc // 未溢出時(shí)會(huì)填充字符串結(jié)束符('\0')buf=[123456789]31 32 33 34 35 36 37 38 39 41 | cc cc // 溢出了將不會(huì)填充字符串結(jié)束符('\0')buf=[123456789A燙?]31 32 33 34 35 36 37 38 39 41 | cc cc // 溢出了將不會(huì)填充字符串結(jié)束符('\0')buf=[123456789A燙?]01 02 03 04 05 06 07 08 09 10 | 11 12-------------------------------------- sprintf31 32 33 34 35 36 37 38 00 cc | cc ccbuf=[12345678]31 32 33 34 35 36 37 38 39 00 | cc ccbuf=[123456789]31 32 33 34 35 36 37 38 39 41 | 00 ccbuf=[123456789A]31 32 33 34 35 36 37 38 39 41 | 42 00buf=[123456789AB]結(jié)論:1. windows上無(wú)snprintf,但是有_snprintf可以達(dá)到同樣的功能,但是細(xì)節(jié)之處略有不同2. 未溢出時(shí),sprintf和snprintf都會(huì)在字符串末尾加上'\0';3. 超出緩沖區(qū)大小時(shí),_snprintf不會(huì)造成溢出,但是不會(huì)在緩沖區(qū)中添加字符結(jié)束符4. sprintf始終會(huì)在字符串末尾添加結(jié)束符,但是存在緩沖區(qū)溢出的情況5. _snprintf比sprintf安全,即不會(huì)造成緩沖區(qū)溢出6. vc6中對(duì)于_snprintf緩沖區(qū)溢出時(shí)不會(huì)出現(xiàn)崩潰信息,但是在vc2010中卻會(huì)出現(xiàn) */


總結(jié)

以上是生活随笔為你收集整理的关于sprintf和snprintf的比较的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。