dsp*_*es1 5 c++ string unicode winapi
我很难将字符串转换为LPWSTR
这样我可以使用该PathStripToRoot()
函数。
好吧,MSDN 文档说我需要LPTSTR
变量(http://msdn.microsoft.com/en-us/library/windows/desktop/bb773757(v=vs.85).aspx),但 Visual Studio 2013 说我需要LPWSTR
.
这是我的函数的代码片段:
fileStat fileCreate(const string& targetFile)
{
fileStat filez;
fstream file(targetFile.c_str());
if (!file)
{
cout << "File does not exist" << endl;
}
std::ifstream in(targetFile, ios::binary | ios::ate);
int a = in.tellg();
cout << "File size(bytes): " << in.tellg() << endl << endl;
file.close();
wstring stemp = strChange(targetFile);
LPCWSTR result = stemp.c_str();
/* Tried the below code but that did not work
LPWSTR ws = new wchar_t[targetFile.size() + 1];
copy(targetFile.begin(), targetFile.end(), ws);
ws[targetFile.size()] = 0;
*/
cout<<"\n\n"<<PathStripToRoot(ws)<<"\n\n";
...
filez.fileSize = a;
return filez;
}
Run Code Online (Sandbox Code Playgroud)
很多人都说要使用MultiByteToWideChar()
函数,但我查看了 MSDN 文档,不知道它是如何工作的。有没有比使用更简单的方法MultiByteToWideChar()
?
在处理 Win32 API 时,您可能希望在现代 Windows 应用程序中使用 Unicode UTF-16 字符串:该类std::wstring
(基于wchar_t
)对于 Visual C++ 来说是可以的。
PathStripToRoot()
然后,您可以使用方便的字符串类而不是原始的类似 C 的字符串缓冲区,将 Win32 C API 包装在一些 C++ 代码中。
以以下带注释的代码为例:
// Set Unicode mode
#define UNICODE
#define _UNICODE
// Windows SDK Headers
#include <Windows.h> // Win32 Platform SDK
#include <Shlwapi.h> // For PathStripToRoot()
#include <Strsafe.h> // For StringCchCopy()
// Standard C++ Headers
#include <exception> // For std::exception
#include <iostream> // For console output
#include <stdexcept> // For std::invalid_argument, std::runtime_error
#include <string> // For std::wstring
// For using PathStripToRoot()
#pragma comment(lib, "Shlwapi.lib")
// C++ wrapper around PathStripToRoot() Win32 API
std::wstring RootFromPath(const std::wstring& path)
{
// Buffer for PathStripToRoot()
wchar_t pathBuffer[MAX_PATH];
// Copy the input string into the buffer.
// Beware of buffer overruns!
HRESULT hr = ::StringCchCopy(pathBuffer, // dest
_countof(pathBuffer), // dest size
path.c_str()); // source
if (hr == STRSAFE_E_INSUFFICIENT_BUFFER)
{
// Copy failed due to insufficient buffer space.
// May accept this case or throw an exception
// based on the context...
// In this case, I just throw here.
throw std::invalid_argument("RootFromPath() - Path string too long.");
}
if (hr != S_OK)
{
throw std::runtime_error("RootFromPath() - StringCchCopy failed.");
}
// Call the Win32 C API using the raw C buffer
if (! ::PathStripToRoot(pathBuffer))
{
// No valid drive letter was found.
// Return an empty string
return std::wstring();
}
// Return a std::wstring with the buffer content
return std::wstring(pathBuffer);
}
// Test
int main()
{
try
{
const std::wstring path = L"C:\\Path1\\Path2";
const std::wstring root = RootFromPath(path);
std::wcout << "The content of the path before is:\t" << path << std::endl;
std::wcout << "RootFromPath() returned: \t" << root << std::endl;
}
catch(const std::exception& ex)
{
std::cerr << "\n*** ERROR: " << ex.what() << std::endl;
}
}
Run Code Online (Sandbox Code Playgroud)
从命令行编译:
Run Code Online (Sandbox Code Playgroud)C:\Temp\CppTests>cl /EHsc /W4 /nologo TestPathStripToRoot.cpp
输出:
Run Code Online (Sandbox Code Playgroud)C:\Temp\CppTests>TestPathStripToRoot.exe The content of the path before is: C:\Path1\Path2 RootFromPath() returned: C:\
关于你的问题的这一点:
好吧,MSDN 文档说我需要
LPTSTR
变量,但 Visual Studios 说我需要LPWSTR
.
LPTSTR
是一个 typedef 等价于TCHAR*
.
LPWSTR
是一个 typedef 等价于WCHAR*
, ie wchar_t*
。
TCHAR
是字符类型的占位符,可以扩展为char
或wchar_t
,具体取决于您是否处于 ANSI/MBCS 还是 Unicode 构建模式。
自 VS2005 以来,Visual Studio 一直默认使用Unicode构建。
因此,除非您正在维护必须使用 ANSI/MBCS 的旧版应用程序,否则只需在现代 Win32 应用程序中使用 Unicode。在这种情况下,您可以直接将wchar_t
基于字符串与 Win32 API 一起使用,而不必担心旧的过时的 TCHAR 模型。
请注意,您的代码中仍然可以包含std::string
s(基于char
- 的),例如表示 Unicode UTF-8文本。您可以在 Win32 API 边界处在UTF-8 ( char
/ std::string
) 和 UTF-16 ( wchar_t
/ ) 之间进行转换。std::wstring
为此,您可以使用一些方便的 RAII 包装器来处理原始 Win32MultiByteToWideChar()
和WideCharToMultiByte()
API。