1. 程式人生 > >StringCbCopy StringCchCopy

StringCbCopy StringCchCopy

--------------------- 本文來自 艾斯曼 的CSDN 部落格 ,全文地址請點選:https://blog.csdn.net/wangqiulin123456/article/details/8193933?utm_source=copy

StringCbCopy函式用於拷貝string,且提供了目標緩衝區的大小作為引數,防止緩衝區溢位等安全問題。

這個函式可用於替換以下函式的使用:

strcpy, wcscpy, _tcscpy

lstrcpy

StrCpy

StringCbCopy函式原型如下:

  1. HRESULT StringCbCopy(

  2. __out LPTSTR pszDest, //目標字串緩衝區

  3. __in size_t cbDest, //目標緩衝區大小(位元組),這個值必須考慮pszSrc加上空結束符’/0’的大小;

  4. //最大執行的位元組數是STRSAFE_MAX_CCH * sizeof(TCHAR)

  5. __in LPCTSTR pszSrc //源字串緩衝區,必須以’/0’結尾

  6. );

函式返回值如下(強烈建議使用SUCCEEDED和FAILED巨集來測試返回值):

S_OK                 //一切OK

STRSAFE_E_INVALID_PARAMETER    //目標緩衝區中值的大小要麼是0,要麼大於最大允許值

STRSAFE_E_INSUFFICIENT_BUFFER  //目標緩衝區大小不夠,資料被截斷;

//當允許資料截斷時,這不算是錯誤

擴充套件函式StringCbCopyEx原型如下:

  1. HRESULT StringCbCopyEx(

  2. __out LPTSTR pszDest, //目標字串緩衝區

  3. __in size_t cbDest, //pszDest的大小(位元組)

  4. __in LPCTSTR pszSrc, //源字串緩衝區

  5. __out_opt LPTSTR *ppszDestEnd, //指向pszDest結尾的指標(指向空結束符處)

  6. __out_opt size_t *pcbRemaining, //pszDest未使用的位元組數,包括空結束符佔用的位元組

  7. __in DWORD dwFlags //取值見下文

  8. );

其中dwFlags可取值如下:

  1. STRSAFE_FILL_BEHIND_NULL //函式執行成功時,dwFlag(0)的低位元組將被用於填充

  2. //pszDest的'/0'之後的未被填充的空間

  3. STRSAFE_IGNORE_NULLS //將空字串指標(null)以空字串TEXT("")對待,可用於模擬lstrcpy

  4. STRSAFE_FILL_ON_FAILURE //函式執行失敗時,dwFlag(0)的低位元組將被用於填充

  5. //pszDest所有的空間,且pszDest以空結束符結束

  6. STRSAFE_NULL_ON_FAILURE //函式執行失敗時,pszDest被設定為空字串TEXT("")

  7. STRSAFE_NO_TRUNCATION //不截斷

函式返回值同StringCbCopy。

還有兩個相似的函式分別是StringCchCopy和StringCchCopyEx,它們和上面兩個函式唯一的區別是StringCchCopy函式是以字元數計數的,而StringCbCopy函式是以位元組數計數的。

(ch表示character;b表示byte),這兩個函式原型如下:

  1. HRESULT StringCchCopy(

  2. __out LPTSTR pszDest,

  3. __in size_t cchDest, //pszDest的大小(字元數)

  4. __in LPCTSTR pszSrc

  5. );

  1. HRESULT StringCchCopyEx(

  2. __out LPTSTR pszDest,

  3. __in size_t cchDest, //pszDest的大小(字元數)

  4. __in LPCTSTR pszSrc,

  5. __out_opt LPTSTR *ppszDestEnd,

  6. __out_opt size_t *pcchRemaining,

  7. __in DWORD dwFlags

  8. );

用法舉例:

獲取當前目錄,在沒有使用strSafe系列函式之前,經典的用法是:

  1. void UnsafeFunc(LPTSTR szPath,DWORD cchPath) {

  2. TCHAR szCWD[MAX_PATH];

  3. GetCurrentDirectory(ARRAYSIZE(szCWD), szCWD);

  4. strncpy(szPath, szCWD, cchPath); //沒有檢查返回值

  5. strncat(szPath, TEXT("//"), cchPath);

  6. strncat(szPath, TEXT("asce.ini"),cchPath);

  7. }

使用strSafe系列函式之後,提高了字串處理的安全性:

  1. bool SaferFunc(LPTSTR szPath,DWORD cchPath) {

  2. TCHAR szCWD[MAX_PATH];

  3. if (GetCurrentDirectory(ARRAYSIZE(szCWD), szCWD) &&

  4. SUCCEEDED(StringCchCopy(szPath, cchPath, szCWD)) &&

  5. SUCCEEDED(StringCchCat(szPath, cchPath, TEXT("//"))) &&

  6. SUCCEEDED(StringCchCat(szPath, cchPath, TEXT("asce.ini")))) {

  7. return true;

  8. }

  9. return false;

  10. }

字元編碼與資料型別

編碼

位元組數

型別

字元(串)常量

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編碼間通用。