C ++ LPSTR和字符串与零终止字符串的麻烦 [英] C++ LPSTR and string trouble with zero-terminated strings

查看:603
本文介绍了C ++ LPSTR和字符串与零终止字符串的麻烦的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 GetOpenFileName 函数从 Winapi ,我应用过滤器到选择文件对话框。



完美工作:

  LPSTR mfilter =Filter\0 * .PDF\0; 
ofn.lpstrFilter = mfilter;

if(GetOpenFileName(& ofn)){
...


$ b b



失败(打开对话框但未应用过滤器) p>

  string mfilter =Filter\0 * .PDF\0; 
ofn.lpstrFilter = mfilter.c_str();

if(GetOpenFileName(& ofn)){
...


$ b b



我需要使用 std:string 因为我通过参数获取文件扩展名,这种类型方便了连接,但我得到不兼容的问题...



这将是我的代码,如果它工作预期(IT失败与上例相同):

  const char * ext =& // Ampersand参数(来自CA Plex)它包含PDF
string mfilter =Filter\0 *。 + ext +\0; //最终字符串:Filter\0 * .PDF\0;
ofn.lpstrFilter = mfilter.c_str();

当我使用这个方法时,我得到运行时异常:

  string mf; 
mf.append(Filter)
.append('\0')
.append(*。pdf)
.append('\0' );

ofn.lpstrFilter = mf.c_str();

GetOpenFileName 函数使用TCHAR,TCHAR在 UNICODE 字符的情况下变为WCHAR



下面是一个例子:

  std :: wstring getOpenFileName(HWND hWnd,const std :: wstring& sFilter)
{
wchar_t buffer [MAX_PATH] = L;

OPENFILENAMEW ofn = {0};

ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hWnd;
ofn.lpstrFilter = sFilter.c_str();
ofn.nFilterIndex = 1;
ofn.lpstrFile = buffer;
ofn.nMaxFile = MAX_PATH;
ofn.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST;

if(!:: GetOpenFileNameW(& ofn))
return L;

返回缓冲区;
}

如果要参数化 lpstrFilter 基于 std :: wstring ,您可以使用 wstring :: c_str() $ c> LPCTSTR 在 UNICODE 的情况下为 const wchar *



重要:问题是 std :: wstring const wchar * 假设输入是一个C字符串。 C字符串'\0'终止,因此解析在到达'\0'字符时停止。为了弥补这一点,您需要使用构造函数,该构造函数需要两个参数指向char数组的指针和长度
也可以使用 string :: push_back()方法来追加NULL。

  std :: wstring sFilter = LPDF文件; 
sFilter.push_back('\0');
sFilter.append(L*。pdf);
sFilter.push_back('\0');


I'm using GetOpenFileName function from Winapi, and I'm applying filter to the select file dialog.

THIS works perfectly:

LPSTR mfilter = "Filter\0*.PDF\0";
ofn.lpstrFilter = mfilter;

if(GetOpenFileName(&ofn)){
...

THIS fails (dialog opens but no filters apply):

string mfilter = "Filter\0*.PDF\0";
ofn.lpstrFilter = mfilter.c_str();

if(GetOpenFileName(&ofn)){
...

I need to use std:string because I'm getting the file extension via parameters and this type facilitates the concatenation but I'm getting incompatibility issues...

This would be my code if it worked as expected (IT FAILS the same as previous example):

const char * ext = &(4:); //Ampersand parameter (from CA Plex) It contains "PDF"
string mfilter = "Filter\0*." + ext + "\0"; //Final string: Filter\0*.PDF\0;
ofn.lpstrFilter = mfilter.c_str();

When I use this method, I'm getting runtime exception:

string mf;
mf.append("Filter")
.append('\0')
.append("*.pdf")
.append('\0');

ofn.lpstrFilter = mf.c_str();

解决方案

The GetOpenFileName function uses TCHARs, and TCHARs become WCHARs in case of UNICODE character set is used.

Here's an example:

std::wstring getOpenFileName(HWND hWnd, const std::wstring& sFilter)
{
    wchar_t buffer[MAX_PATH] = L"";

    OPENFILENAMEW ofn = {0};

    ofn.lStructSize = sizeof(ofn);
    ofn.hwndOwner = hWnd;
    ofn.lpstrFilter = sFilter.c_str();
    ofn.nFilterIndex = 1;
    ofn.lpstrFile = buffer;
    ofn.nMaxFile = MAX_PATH;
    ofn.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST;

    if( !::GetOpenFileNameW( &ofn ) )
        return L"";

    return buffer;
}

If you want to parametrize lpstrFilter based on std::wstring you can just use wstring::c_str() to get LPCTSTR which is const wchar* in case of UNICODE.

IMPORTANT: The problem is that the std::wstring constructor that takes a const wchar* assumes the input is a C string. C strings are '\0' terminated and thus parsing stops when it reaches the '\0' character. To compensate for this you need to use the constructor that takes two parameters a pointer to the char array and a length. You can also use string::push_back() method to append NULLs.

std::wstring sFilter = L"PDF Files";
sFilter.push_back('\0');
sFilter.append(L"*.pdf");
sFilter.push_back('\0');

这篇关于C ++ LPSTR和字符串与零终止字符串的麻烦的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆