将字符串转换为 LPWSTR

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()

Mr.*_*C64 2

在处理 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)

从命令行编译:

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:\
Run Code Online (Sandbox Code Playgroud)

关于你的问题的这一点:

好吧,MSDN 文档说我需要LPTSTR变量,但 Visual Studios 说我需要LPWSTR.

LPTSTR是一个 typedef 等价于TCHAR*.
LPWSTR是一个 typedef 等价于WCHAR*, ie wchar_t*

TCHAR是字符类型的占位符,可以扩展为charwchar_t,具体取决于您是否处于 ANSI/MBCS 还是 Unicode 构建模式。

自 VS2005 以来,Visual Studio 一直默认使用Unicode构建。

因此,除非您正在维护必须使用 ANSI/MBCS 的旧版应用程序,否则只需在现代 Win32 应用程序中使用 Unicode。在这种情况下,您可以直接将wchar_t基于字符串与 Win32 API 一起使用,而不必担心旧的过时的 TCHAR 模型。

请注意,您的代码中仍然可以包含std::strings(基于char- 的),例如表示 Unicode UTF-8文本。您可以在 Win32 API 边界处在UTF-8 ( char/ std::string) 和 UTF-16 ( wchar_t/ ) 之间进行转换。std::wstring

为此,您可以使用一些方便的 RAII 包装器来处理原始 Win32MultiByteToWideChar()WideCharToMultiByte()API