int main() { char strHelloWorld1[] = { "hello" }; char strHelloWorld2[] = { "world1" }; char strHelloWorld3[MAX_LEN_NUM] = { 0 }; strncpy(strHelloWorld3, strHelloWorld2, 2); strcat(strHelloWorld2, "Welcome to C++"); return 0; }
Q: 對於這么一段代碼,在VS運行程序時會出現下列警告,檢查嚴格時會直接報錯 This function or variable may be unsafe.
解決起來也容易,程序開頭進行宏定義 #define _CRT_SECURE_NO_WARNINGS 或者 項目 - 屬性 - 配置 - C/C++ - 預處理器 - 預處理器定義里添加:_CRT_SECURE_NO_WARNINGS。
strcat哪里不安全??
調試上述代碼,會發現strHelloWorld2只有6字節,進行連接操作時,發生緩沖區溢出,影響了strHelloWorld1。
strcat_s和strcpy_s的簡單用法
1、strcat_s
errno_t strcat_s(char * restrict dest,rsize_t destsz,const char * restrict src);
功能:把src所指字符串添加到dest結尾處(覆蓋dest結尾處的'\0')並添加'\0'。
參數
- strDestination : Null 終止的目標字符緩沖區。
- munberOFEIements:目標字符串緩沖區的大小。
- strSource:Null 終止的源字符串緩沖區。
返回值:
- 0:成功
- EINVAL:目標字符串或者源字符串沒有初始化
- ERANGE:越界
如果dest <strlen(dest)+ strlen(src)+1 <= destsz所指向的字符數組的大小,則行為未定義;
2、strcpy_s
errno_t strcpy_s(char * restrict dest,rsize_t destsz,const char * restrict src);
- dest-指向要寫入的字符數組的指針
- src-指向要復制的空終止字節字符串的指針
- destsz-寫入的最大字符數,典型地為目標緩沖區的大小,理論上不能超過RSIZE_MAX
char s1[5]; // sizeof(s1) >= dest_size > strlen(src)
strcpy_s(s1, 4, "AA"); // "AA" // sizeof(s1) >= dest_size <= strlen(src)
strcpy_s(s1, 1, "AA"); // 程序異常退出 // sizeof(s1) >= dest_size > strlen(src)
strcpy_s(s1, sizeof(s1), "AA"); // "AA"
3、strnlen_s
strlen計算時,一定要確保字符數組是以空字符結束的,如果沒有則可能沿着數組在內存中的位置不斷向前尋找,知道遇到空字符才停下來。而strlen_s限制住了掃描范圍所以不會出事。
聲明:
size_t strnlen(const char *str, size_t numberOfElements);
參數:
str -- 要計算的字符串
numberOfElements -- 最大數量的字符進行檢查
返回值:
如果在剛開始的numberOfElements長度里找到不到空字符,則返回numberOfElements。
如果字符串長度小於numberOfElements,且字符串結尾有空字符則返回字符串長度,如果結尾沒有空字符,則返回numberOfElements。
#include "stdafx.h" #include <iostream> #include <cstring>
int main(){ char str[] = "Hello,world"; size_t len = strnlen_s(str, 5); std::cout << "length is " << len << std::endl; return 0; } 結果輸出: length is 5 請按任意鍵繼續. . .
不錯的文檔網站:https://cloud.tencent.com/developer/doc/1024
dest | - | 指向要寫入的字符數組的指針 |
src | - | 指向要復制的空終止字節字符串的指針 |
destsz | - | 寫入的最大字符數,典型地為目標緩沖區的大小 |