将LPSTR文件路径中的反斜杠替换为双反斜杠或正斜杠

Replacing backslash with double backslash or forward slash in LPSTR filepath

本文关键字:替换 LPSTR 文件 路径      更新时间:2023-10-16

我正在尝试向WIN32 API发布消息以打开WAV文件。我可以通过将LPARAM参数设置为L"C:\/path/file.wav"来实现这一点!然而,我一直在尝试使用对话框来生成文件路径的字符串。OpenFileDialog函数可以将选定的文件路径作为LPSTR数据类型返回,这听起来很完美!但是,该文件路径被识别为windows文件路径,因此由反斜杠组成。由于这些反斜杠没有转义或替换为正斜杠,因此编译器会因为格式不正确的通用字符名而开始哭泣。因此,将LPSTR文件路径中的所有\替换为\或/似乎很简单。我一直在尝试用几种方法来做到这一点,但似乎都不起作用。

wchar_t* SelectAudioFile(HWND windowHandle) {
    OPENFILENAME ofn;      // common dialog box structure
    char szFile[260];      // buffer for file name
    // Initialize OPENFILENAME
    ZeroMemory(&ofn, sizeof(ofn));
    ofn.lStructSize = sizeof(ofn);
    ofn.hwndOwner = windowHandle;
    ofn.lpstrFile = (LPWSTR)szFile;
    ofn.lpstrFile[0] = '';
    ofn.nMaxFile = sizeof(szFile);
    ofn.lpstrFilter = L"Waveform Audio File Format (*.wav)*.wav";
    ofn.nFilterIndex = 1;
    ofn.lpstrFileTitle = NULL;
    ofn.nMaxFileTitle = 0;
    ofn.lpstrInitialDir = NULL;
    ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
    // Display the Open dialog box.
    if (GetOpenFileName(&ofn)==TRUE) {
        CreateFile(ofn.lpstrFile,
            GENERIC_READ,
            0,
            (LPSECURITY_ATTRIBUTES) NULL,
            OPEN_EXISTING,
            FILE_ATTRIBUTE_NORMAL,
            (HANDLE) NULL);
        MessageBox(windowHandle,ofn.lpstrFile,0,0);
    }
     //Here the backslash should be escaped or replaced.
    const wchar_t * currentPath = ofn.lpstrFile; //This is a LPSTR 
    wchar_t * newPath;
    int filePathLength = sizeof(currentPath);
    for (int i=0; i < filePathLength; i++) {
        if (currentPath[i] == "\") {
            newPath[i] = "\\";
        } else {
            newPath[i] = filePath[i];
        }
    }
    return newPath;

}

下面的行将发布一条消息,告诉它在路径上打开某个文件

PostMessageW(hwnd, WMA_OPEN, 0, (LPARAM)SelectAudioFile(hwnd)); 

因此,用静态文件路径替换LPARAM是可行的!

我应该如何替换文件路径中的反斜杠?

万分感谢!

您的代码有几个问题:

  1. 您错误地混合了Ansi和Unicode。

  2. 您正在返回一个指向未分配任何内存的本地缓冲区的指针。

  3. 您正在使用PostMessage()异步发布一个本地缓冲区,该缓冲区可能超出范围并在窗口处理消息之前变得无效。

  4. 即使GetOpenFileName()失败或被取消,您也在发布消息。

试试这个:

bool SelectAudioFile(HWND windowHandle, wchar_t *audioFile, int maxAudioFile)
{
    OPENFILENAMEW ofn = {0};
    ofn.lStructSize = sizeof(ofn);
    ofn.hwndOwner = windowHandle;
    ofn.lpstrFile = audioFile;
    ofn.nMaxFile = maxAudioFile;
    ofn.lpstrFilter = L"Waveform Audio File Format (*.wav)*.wav";
    ofn.nFilterIndex = 1;
    ofn.lpstrFileTitle = NULL;
    ofn.nMaxFileTitle = 0;
    ofn.lpstrInitialDir = NULL;
    ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
    if (GetOpenFileNameW(&ofn))
    {
        MessageBoxW(windowHandle, audioFile, 0, 0);
        return true;
    }
    return false;
}

wchar_t szAudioFile[MAX_PATH+1] = {0};
if (SelectAudioFile(hwnd, szAudioFile, MAX_PATH))
    SendMessageW(hwnd, WMA_OPEN, 0, (LPARAM)szAudioFile); 

或者:

#include <string>
std::wstring SelectAudioFile(HWND windowHandle)
{
    OPENFILENAMEW ofn = {0};
    wchar_t szFile[MAX_PATH+1] = {0};
    ofn.lStructSize = sizeof(ofn);
    ofn.hwndOwner = windowHandle;
    ofn.lpstrFile = szFile;
    ofn.nMaxFile = MAX_PATH;
    ofn.lpstrFilter = L"Waveform Audio File Format (*.wav)*.wav";
    ofn.nFilterIndex = 1;
    ofn.lpstrFileTitle = NULL;
    ofn.nMaxFileTitle = 0;
    ofn.lpstrInitialDir = NULL;
    ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
    if (GetOpenFileNameW(&ofn))
        MessageBoxW(windowHandle, szFile, 0, 0);
    return szFile;
}

std::wstring audioFile = SelectAudioFile(hwnd);
if (audioFile.length() > 0)
    SendMessageW(hwnd, WMA_OPEN, 0, (LPARAM)audioFile.c_str()); 

我同意Cody Gray的观点,即您只需要对字符串文本进行转义backlash,并且您的代码中似乎混合了Unicode和非Unicode字符;如果您的项目使用Unicode字符集,则需要更改以下内容:

  • szFile的类型应为wchar_t(手动转换类型时请务必小心!)
  • 应为ofn.nMaxFile分配_countof(szFile)而不是sizeof()
  • CreateFile()的调用似乎没有必要
  • 应为filePathLength分配strlen(currentPath),而不是sizeof(currentPath)
  • 如果返回指向szFile[]的指针,则szFile需要声明为静态或定义为函数外的全局变量

/替换newPath是一个本地指针,您没有为它分配内存,然后返回这个值,所以即使您将它声明为wchar_t newPath[_MAX_PATH],当函数返回时,内存地址也将无效——最好只替换currentPath的值。