strcpy、strncpy、strncpy_s和snprintf
1、strcpy
原型宣告: extern char *strcpy(char* dest, const char *src);依據源串的\0作為結束判斷的,不會檢查需要拷貝的緩衝區的大小,如果目標空間不夠,就有溢位問題。
2、strncpy
原型
char* strncpy(char*dest,char*src,size_t n);
複製字串src中的內容(字元,數字、漢字....)到字串dest中,複製多少由size_t的值決定,返回指向dest的指標。如果遇到空字元('\0'),則空字元後面為原來的字元
程式碼如下:
dest[]="Hell99iam!"; src[]="abc\0def"; strncpy(dest,src,5);
此時,dest區域是這樣的:'a','b','c','\0','\0','9','i','a','m','!'
而非這樣:'a','b','c','\0','\0','\0','\0','\0','\0','\0'
'\0','\0'並不是新增在'!'的後面。可以用for迴圈輸出每個元素的ascii來確定。
strncpy是字串拷貝推薦的用法
3、strncpy_s
原型:
errno_t strncpy_s(
char *strDest,
size_t numberOfElements,
const char *strSource,
size_t count
);
引數numberOfElements表明dest中的位元組數,防止目標指標dest中的空間不夠,同時返回值改成返回錯誤程式碼,而不是返回char*。
會在字串結束處填補一個空字元。
count引數需要小於目標緩衝區大小。
如果情況如下程式碼:
char dst[5];
strncpy_s(dst, sizeof(dst), "a long string", 5);
表示使用strncpy_s 拷貝5個位元組到dst緩衝區,使得沒用多餘空間給空字元結束符,填補空字元時會溢位,並呼叫異常處理控制代碼。
需要補空字元時使用 _TRUNCATE 或者 (size – 1)
程式碼如下:
char dst[5]; strncpy_s(dst, sizeof(dst), "a long string", _TRUNCATE); strncpy_s(dst, sizeof(dst), "a long string", sizeof(dst)-1);
跟strncpy不一樣,當count引數比源字串長時,strncpy_s 不會一直補空字元到指定長度。
如果源地址字串和目標地址字串重疊,則結果未定義。
_s版本函式並不是標準庫,不推薦使用
4、snprintf
原型:
int snprintf(char *str, size_t size, const char *format, ...)
將可變個引數(...)按照format格式化成字串,然後將其複製到str中
(1) 如果格式化後的字串長度 < size,則將此字串全部複製到str中,並給其後新增一個字串結束符('\0');
(2) 如果格式化後的字串長度 >= size,則只將其中的(size-1)個字元複製到str中,並給其後新增一個字串結束符('\0'),返回值為欲寫入的字串長度。
#include <stdio.h>
int main () {
char a[16];
size_t i;
i = snprintf(a, 13, "%012d", 12345); // 第 1 種情況
printf("i = %lu, a = %s\n", i, a); // 輸出:i = 12, a = 000000012345
i = snprintf(a, 9, "%012d", 12345); // 第 2 種情況
printf("i = %lu, a = %s\n", i, a); // 輸出:i = 12, a = 00000001
return 0;
}