StringCchCopy
基本概述
StringCchCopy是Windows提供的字符串安全拷贝函数,属于StrSafe.h头文件下的StrSafe库,目的是替代传统的strcpy等字符串拷贝函数(避免缓冲区溢出),它会严格检查目标缓冲区的大小,确保拷贝操作不会越界,提升代码安全性。
基本语法
1 2 3 4 5
| STRSAFEAPI StringCchCopyA( [out] STRSAFE_LPSTR pszDest, [in] size_t cchDest, [in] STRSAFE_LPCSTR pszSrc );
|
返回值
HRESULT类型,常见返回值:
S_OK:拷贝成功,且目标字符串以\0终止。
STRSAFE_E_INSUFFICIENT_BUFFER:目标缓冲区空间不足,拷贝失败(此时目标缓冲区会被置为空字符串)。
数据类型
STRSAFE_LPSTR:
1
| typedef _Null_terminated_ char* STRSAFE_LPSTR;
|
_Null_terminated_:空终止属性标注;
这是微软编译器(MSVC)的批注(Annotation),不是标准C/C++关键字,作用是:
告诉编译器 / 静态分析工具:这个指针指向的字符串必须是以'\0'结尾的空终止字符串。
STRSAFE_LPCSTR:
1
| typedef _Null_terminated_ const char* STRSAFE_LPCSTR;
|
代表只读、空终止的窄字符串指针,相比STRSAFE_LPSTR多了const,只能读取字符串内容,不能修改。
简单示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| #include <Windows.h> #include <StrSafe.h> #pragma comment(lib, "StrSafe.lib")
int main() { wchar_t szDest[10] = { 0 }; LPCWSTR szSrc = L"Hello World";
HRESULT hr = StringCchCopy(szDest, _countof(szDest), szSrc);
if (SUCCEEDED(hr)) { wprintf(L"拷贝成功:%s\n", szDest); } else if (hr == STRSAFE_E_INSUFFICIENT_BUFFER) { wprintf(L"拷贝失败:目标缓冲区空间不足\n"); wprintf(L"当前目标缓冲区内容:%s\n", szDest); } else { wprintf(L"拷贝失败:未知错误,错误码:0x%X\n", hr); }
wchar_t szDest2[10] = { 0 }; LPCWSTR szSrc2 = L"Hello"; hr = StringCchCopy(szDest2, _countof(szDest2), szSrc2); if (SUCCEEDED(hr)) { wprintf(L"\n成功示例:%s\n", szDest2); }
return 0; }
|
ExpandEnvironmentStrings
基本概述
ExpandEnvironmentStrings是Windows提供的环境变量解析函数,属于Windows.h头文件,常用于将包含环境变量占位符的字符串(如%SystemRoot%\System32)转换为实际的路径(如C:\Windows\System32),是处理系统路径、用户目录等场景的常用工具。
基本语法
1 2 3 4 5 6 7 8 9 10 11 12 13
| DWORD ExpandEnvironmentStringsW( [in] LPCWSTR lpSrc, [out, optional] LPWSTR lpDst, [in] DWORD nSize );
DWORD ExpandEnvironmentStringsA( [in] LPCSTR lpSrc, [out, optional] LPSTR lpDst, [in] DWORD nSize );
|
返回值
成功:返回解析后字符串的字符数(ANSI是字节数,Unicode是wchar_t字符数),不包含终止符\0。
失败:返回0;若目标缓冲区太小,返回值会大于nSize(提示所需的最小缓冲区大小)。
简单示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| #include <Windows.h> #include <wchar.h>
int main() { LPCWSTR szSrc = L"%USERPROFILE%\\Desktop\\test.txt"; DWORD dwRequiredSize = 0;
dwRequiredSize = ExpandEnvironmentStringsW(szSrc, NULL, 0); if (dwRequiredSize == 0) { wprintf(L"获取缓冲区大小失败,错误码:%d\n", GetLastError()); return 1; }
wchar_t* szDest = new wchar_t[dwRequiredSize + 1]; if (szDest == NULL) { wprintf(L"内存分配失败\n"); return 1; }
DWORD dwResult = ExpandEnvironmentStringsW(szSrc, szDest, dwRequiredSize + 1); if (dwResult == 0 || dwResult > dwRequiredSize + 1) { wprintf(L"解析失败,错误码:%d\n", GetLastError()); delete[] szDest; return 1; }
wprintf(L"源字符串:%s\n", szSrc); wprintf(L"解析后:%s\n", szDest);
wchar_t szDest2[MAX_PATH] = { 0 }; LPCWSTR szSrc2 = L"%TEMP%\\temp_file.tmp"; dwResult = ExpandEnvironmentStringsW(szSrc2, szDest2, MAX_PATH); if (dwResult > 0 && dwResult <= MAX_PATH) { wprintf(L"\n源字符串:%s\n", szSrc2); wprintf(L"解析后:%s\n", szDest2); } else { wprintf(L"\n解析失败,所需缓冲区大小:%d,当前缓冲区大小:%d\n", dwResult, MAX_PATH); }
delete[] szDest; return 0; }
|
StringCchPrintf
基本概述
StringCchPrintf是StrSafe库的核心函数,替代传统sprintf/swprintf等打印函数,核心优势是通过严格检查缓冲区字符数避免溢出,它的本质是 “格式化字符串 + 安全写入缓冲区”,支持和printf完全一致的格式化语法,但更安全、更易排查错误。
基本语法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| STRSAFEAPI StringCchPrintfW( [out] STRSAFE_LPWSTR pszDest, [in] size_t cchDest, [in] STRSAFE_LPCWSTR pszFormat, ... );
STRSAFEAPI StringCchPrintfA( [out] STRSAFE_LPSTR pszDest, [in] size_t cchDest, [in] STRSAFE_LPCSTR pszFormat, ... );
|
简单示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| #include <Windows.h> #include <StrSafe.h> #pragma comment(lib, "StrSafe.lib")
int main() { wchar_t buf[50] = { 0 }; HRESULT hr = StringCchPrintfW( buf, _countof(buf), L"姓名:%s,年龄:%d,身高:%.2f米", L"李四", 25, 1.75 );
if (SUCCEEDED(hr)) { wprintf(L"格式化结果:%s\n", buf); } else { wprintf(L"失败,错误码:0x%X\n", hr); }
return 0; }
|