StringCbCopy StringCchCopy
--------------------- 本文來自 艾斯曼 的CSDN 部落格 ,全文地址請點選:https://blog.csdn.net/wangqiulin123456/article/details/8193933?utm_source=copy
StringCbCopy函式用於拷貝string,且提供了目標緩衝區的大小作為引數,防止緩衝區溢位等安全問題。
這個函式可用於替換以下函式的使用:
strcpy, wcscpy, _tcscpy
lstrcpy
StrCpy
StringCbCopy函式原型如下:
-
HRESULT StringCbCopy(
-
__out LPTSTR pszDest, //目標字串緩衝區
-
__in size_t cbDest, //目標緩衝區大小(位元組),這個值必須考慮pszSrc加上空結束符’/0’的大小;
-
//最大執行的位元組數是STRSAFE_MAX_CCH * sizeof(TCHAR)
-
__in LPCTSTR pszSrc //源字串緩衝區,必須以’/0’結尾
-
);
函式返回值如下(強烈建議使用SUCCEEDED和FAILED巨集來測試返回值):
S_OK //一切OK
STRSAFE_E_INVALID_PARAMETER //目標緩衝區中值的大小要麼是0,要麼大於最大允許值
STRSAFE_E_INSUFFICIENT_BUFFER //目標緩衝區大小不夠,資料被截斷;
//當允許資料截斷時,這不算是錯誤
擴充套件函式StringCbCopyEx原型如下:
-
HRESULT StringCbCopyEx(
-
__out LPTSTR pszDest, //目標字串緩衝區
-
__in size_t cbDest, //pszDest的大小(位元組)
-
__in LPCTSTR pszSrc, //源字串緩衝區
-
__out_opt LPTSTR *ppszDestEnd, //指向pszDest結尾的指標(指向空結束符處)
-
__out_opt size_t *pcbRemaining, //pszDest未使用的位元組數,包括空結束符佔用的位元組
-
__in DWORD dwFlags //取值見下文
-
);
其中dwFlags可取值如下:
-
STRSAFE_FILL_BEHIND_NULL //函式執行成功時,dwFlag(0)的低位元組將被用於填充
-
//pszDest的'/0'之後的未被填充的空間
-
STRSAFE_IGNORE_NULLS //將空字串指標(null)以空字串TEXT("")對待,可用於模擬lstrcpy
-
STRSAFE_FILL_ON_FAILURE //函式執行失敗時,dwFlag(0)的低位元組將被用於填充
-
//pszDest所有的空間,且pszDest以空結束符結束
-
STRSAFE_NULL_ON_FAILURE //函式執行失敗時,pszDest被設定為空字串TEXT("")
-
STRSAFE_NO_TRUNCATION //不截斷
函式返回值同StringCbCopy。
還有兩個相似的函式分別是StringCchCopy和StringCchCopyEx,它們和上面兩個函式唯一的區別是StringCchCopy函式是以字元數計數的,而StringCbCopy函式是以位元組數計數的。
(ch表示character;b表示byte),這兩個函式原型如下:
-
HRESULT StringCchCopy(
-
__out LPTSTR pszDest,
-
__in size_t cchDest, //pszDest的大小(字元數)
-
__in LPCTSTR pszSrc
-
);
-
HRESULT StringCchCopyEx(
-
__out LPTSTR pszDest,
-
__in size_t cchDest, //pszDest的大小(字元數)
-
__in LPCTSTR pszSrc,
-
__out_opt LPTSTR *ppszDestEnd,
-
__out_opt size_t *pcchRemaining,
-
__in DWORD dwFlags
-
);
用法舉例:
獲取當前目錄,在沒有使用strSafe系列函式之前,經典的用法是:
-
void UnsafeFunc(LPTSTR szPath,DWORD cchPath) {
-
TCHAR szCWD[MAX_PATH];
-
GetCurrentDirectory(ARRAYSIZE(szCWD), szCWD);
-
strncpy(szPath, szCWD, cchPath); //沒有檢查返回值
-
strncat(szPath, TEXT("//"), cchPath);
-
strncat(szPath, TEXT("asce.ini"),cchPath);
-
}
使用strSafe系列函式之後,提高了字串處理的安全性:
-
bool SaferFunc(LPTSTR szPath,DWORD cchPath) {
-
TCHAR szCWD[MAX_PATH];
-
if (GetCurrentDirectory(ARRAYSIZE(szCWD), szCWD) &&
-
SUCCEEDED(StringCchCopy(szPath, cchPath, szCWD)) &&
-
SUCCEEDED(StringCchCat(szPath, cchPath, TEXT("//"))) &&
-
SUCCEEDED(StringCchCat(szPath, cchPath, TEXT("asce.ini")))) {
-
return true;
-
}
-
return false;
-
}
字元編碼與資料型別
編碼 |
位元組數 |
型別 |
字元(串)常量 |
WinNT.h中的定義 |
ANSI |
8bit |
char |
'A' "A string" |
typedef char CHAR; typedef CHAR *PCHAR; typedef CHAR *PSTR; typedef CONST CHAR *PCSTR; |
Unicode (UTF-16) |
16bit |
wchar_t 通過編譯器設定/Zc:wchar_t支援 |
L'A' L"A string" |
typedef wchar_t WCHAR; typedef WCHAR *PWCHAR; typedef WCHAR *PWSTR; typedef CONST WCHAR *PCWSTR; |
WinNT.h標頭檔案中定義字元型別巨集,TCHAR、PTCHAR、PTSTR、PCTSTR、TEXT(),可在ANSI和Unicode編碼間通用。