C ++ LPSTR和字符串与零终止字符串的麻烦 [英] C++ LPSTR and string trouble with zero-terminated strings
问题描述
我使用 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();
下面是一个例子:
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屋!