C++ 简单 IF 子句更改静态 const char 变量的值
C++ Simple IF clause changes value of a static const char variable
好的,我已经处理了两天了,我找不到解决方案。
问题: 我正在尝试使用 Winapi 为 文件选择对话框 设置过滤器。我正在使用 GetOpenFileName
函数来执行此操作。此函数使用 结构 来设置选项,例如文件扩展名过滤器。这个名为 lpstrFilter
的结构成员需要特定的字符串格式。我完全按照 Winapi 指示设置该字符串,但由于某种原因,该字符串的值发生了变化。
我有这个 static const char *:
//This contains string "JPG"
static const char * extensionFilter = v->trabajo10.C_JMV_SelectFile_FileExtension7.GetString();
//This forms a filter string which applies to OPENFILENAME structure.
string sFilter;
sFilter.append("Format: ");
sFilter.append(extensionFilter);
sFilter.push_back('[=10=]');
sFilter.append("*.");
sFilter.append(extensionFilter);
sFilter.push_back('[=10=]');
const char * filter = sFilter.c_str();
ofn.lpstrFilter = filter; //This sets: --> Format: JPG[=10=]*.JPG[=10=]
//This opens the file selection dialog
if (GetOpenFileName(&ofn)==TRUE){
...
文件选择对话框看起来正确,如下所示:
笑话来了,我把代码修改成这样:
//This contains string "JPG"
static const char * extensionFilter = v->trabajo10.C_JMV_SelectFile_FileExtension7.GetString();
if(1){
//This forms a filter string which applies to OPENFILENAME structure.
string sFilter;
sFilter.append("Format: ");
sFilter.append(extensionFilter);
sFilter.push_back('[=11=]');
sFilter.append("*.");
sFilter.append(extensionFilter);
sFilter.push_back('[=11=]');
const char * filter = sFilter.c_str();
ofn.lpstrFilter = filter; //This sets: --> Format: JPG[=11=]*.JPG[=11=]
}
//This opens the file selection dialog
if (GetOpenFileName(&ofn)==TRUE){
...
这就是结果,问题所在:
过滤字符串被修改了???
if(1){
//This forms a filter string which applies to OPENFILENAME structure.
string sFilter;
sFilter.append("Format: ");
sFilter.append(extensionFilter);
sFilter.push_back('[=10=]');
sFilter.append("*.");
sFilter.append(extensionFilter);
sFilter.push_back('[=10=]');
const char * filter = sFilter.c_str();
ofn.lpstrFilter = filter; //This sets: --> Format: JPG[=10=]*.JPG[=10=]
}
sFilter
变量的生命周期在它声明的块结束时结束。 sFilter.c_str()
返回的指针在sFilter
被修改或销毁之前一直有效。
您在该指针失效后使用它。这与您昨天遇到的问题相同,我在对该问题的评论中猜到了。这就是为什么您需要展示完整的 MCVE。这个问题看起来也与您一周前提出的问题重复:。我建议您花一些时间来确保您完全理解 c_str()
.
返回值的有效性
您必须确保 sFilter
在您使用完指针之前一直存在。在外部块中声明 sFilter
以确保。
问题是您有一个超出范围的变量
if(1){
string sFilter;
// ... code
// Right here
const char * filter = sFilter.c_str();
ofn.lpstrFilter = filter;
}
该块结束后 filter
超出范围,因此 ofn.lpstrFilter
有一个悬空指针。
回答 ProtectedVoid 对声明未使用对象的担忧:想象一下 std::string
是一个昂贵的对象并且这种情况不太可能发生。除非条件为真,否则您不希望构造对象。但它必须持续超出条件的范围。所以我们使用默认构造的 unique_ptr
比默认构造的 string
:
便宜得多的事实
std::unique_ptr<std::string> scope_extender;
if( something unlikely ){
//This forms a filter string which applies to OPENFILENAME structure.
std::string* sFilter = new std::string;
scope_extender.reset( sFilter );
sFilter->append("Format: ");
sFilter->append(extensionFilter);
sFilter->push_back('[=10=]');
sFilter->append("*.");
sFilter->append(extensionFilter);
sFilter->push_back('[=10=]');
const char * filter = sFilter->c_str();
ofn.lpstrFilter = filter; //This sets: --> Format: JPG[=10=]*.JPG[=10=]
}
显然,我不想暗示 std::string
的建造成本足够高,值得所有这些麻烦。但是在类似情况下的某些对象可能是。此外,有人评论说如果一个条件中有许多次要对象会怎样。在这种情况下,您需要一个实用程序结构将它们全部保存在一起,并且 unique_ptr 有条件地拥有该结构。
好的,我已经处理了两天了,我找不到解决方案。
问题: 我正在尝试使用 Winapi 为 文件选择对话框 设置过滤器。我正在使用 GetOpenFileName
函数来执行此操作。此函数使用 结构 来设置选项,例如文件扩展名过滤器。这个名为 lpstrFilter
的结构成员需要特定的字符串格式。我完全按照 Winapi 指示设置该字符串,但由于某种原因,该字符串的值发生了变化。
我有这个 static const char *:
//This contains string "JPG"
static const char * extensionFilter = v->trabajo10.C_JMV_SelectFile_FileExtension7.GetString();
//This forms a filter string which applies to OPENFILENAME structure.
string sFilter;
sFilter.append("Format: ");
sFilter.append(extensionFilter);
sFilter.push_back('[=10=]');
sFilter.append("*.");
sFilter.append(extensionFilter);
sFilter.push_back('[=10=]');
const char * filter = sFilter.c_str();
ofn.lpstrFilter = filter; //This sets: --> Format: JPG[=10=]*.JPG[=10=]
//This opens the file selection dialog
if (GetOpenFileName(&ofn)==TRUE){
...
文件选择对话框看起来正确,如下所示:
笑话来了,我把代码修改成这样:
//This contains string "JPG"
static const char * extensionFilter = v->trabajo10.C_JMV_SelectFile_FileExtension7.GetString();
if(1){
//This forms a filter string which applies to OPENFILENAME structure.
string sFilter;
sFilter.append("Format: ");
sFilter.append(extensionFilter);
sFilter.push_back('[=11=]');
sFilter.append("*.");
sFilter.append(extensionFilter);
sFilter.push_back('[=11=]');
const char * filter = sFilter.c_str();
ofn.lpstrFilter = filter; //This sets: --> Format: JPG[=11=]*.JPG[=11=]
}
//This opens the file selection dialog
if (GetOpenFileName(&ofn)==TRUE){
...
这就是结果,问题所在:
过滤字符串被修改了???
if(1){
//This forms a filter string which applies to OPENFILENAME structure.
string sFilter;
sFilter.append("Format: ");
sFilter.append(extensionFilter);
sFilter.push_back('[=10=]');
sFilter.append("*.");
sFilter.append(extensionFilter);
sFilter.push_back('[=10=]');
const char * filter = sFilter.c_str();
ofn.lpstrFilter = filter; //This sets: --> Format: JPG[=10=]*.JPG[=10=]
}
sFilter
变量的生命周期在它声明的块结束时结束。 sFilter.c_str()
返回的指针在sFilter
被修改或销毁之前一直有效。
您在该指针失效后使用它。这与您昨天遇到的问题相同,我在对该问题的评论中猜到了。这就是为什么您需要展示完整的 MCVE。这个问题看起来也与您一周前提出的问题重复:c_str()
.
您必须确保 sFilter
在您使用完指针之前一直存在。在外部块中声明 sFilter
以确保。
问题是您有一个超出范围的变量
if(1){
string sFilter;
// ... code
// Right here
const char * filter = sFilter.c_str();
ofn.lpstrFilter = filter;
}
该块结束后 filter
超出范围,因此 ofn.lpstrFilter
有一个悬空指针。
回答 ProtectedVoid 对声明未使用对象的担忧:想象一下 std::string
是一个昂贵的对象并且这种情况不太可能发生。除非条件为真,否则您不希望构造对象。但它必须持续超出条件的范围。所以我们使用默认构造的 unique_ptr
比默认构造的 string
:
std::unique_ptr<std::string> scope_extender;
if( something unlikely ){
//This forms a filter string which applies to OPENFILENAME structure.
std::string* sFilter = new std::string;
scope_extender.reset( sFilter );
sFilter->append("Format: ");
sFilter->append(extensionFilter);
sFilter->push_back('[=10=]');
sFilter->append("*.");
sFilter->append(extensionFilter);
sFilter->push_back('[=10=]');
const char * filter = sFilter->c_str();
ofn.lpstrFilter = filter; //This sets: --> Format: JPG[=10=]*.JPG[=10=]
}
显然,我不想暗示 std::string
的建造成本足够高,值得所有这些麻烦。但是在类似情况下的某些对象可能是。此外,有人评论说如果一个条件中有许多次要对象会怎样。在这种情况下,您需要一个实用程序结构将它们全部保存在一起,并且 unique_ptr 有条件地拥有该结构。