如何在保留'\ 0'字符的同时将std :: string转换为LPCSTR?
我想在OPENFILENAME.lpstrFilter上使用结果,该结果要求过滤器包含'\ 0'作为分隔符。
std :: string.c_str()似乎剥离并修剪'\ 0'
提前致谢!
==========================
(如何在论坛中正确添加评论作为回复帖子?)
阅读完评论后,我继续仔细检查这个片段:
std::string filter = "Terrain Configuration (*.tcfg)\0*.tcfg\0\0";
const char* f1 = "Terrain Configuration (*.tcfg)\0*.tcfg\0\0";
const char* f2 = filter.c_str();
for(int i = 0; i < 50; i++)
{
char c1 = *(f1 + i); // works
char c2 = *(f2 + i); // doesn't work. beyond the first \0, it's garbage.
}
我是否错误地了解了c_str()或LPCSTR的工作原理?
答案 0 :(得分:6)
C_STR不会删除NUL字符。错误可能与构造STD :: string的方式有关。
答案 1 :(得分:5)
一般来说,std :: string正确处理嵌入的'\ 0'字符。
但是,当与const char *接口时,必须格外小心。
在这种情况下,在构造字符串期间已经出现问题:
std::string filter = "Terrain Configuration (*.tcfg)\0*.tcfg\0\0"; // wrong
在这里,您可以从const char *构造一个std :: string。由于构造函数不知道用于构造std :: string的字符数,因此它会在第一个'\ 0'处停止。
可以自己逐个复制字符,但有一种更好的方法:使用需要两个迭代器到char数组的构造函数,一个使用begin,另一个使用end:
const char filter_[] = "Terrain Configuration (*.tcfg)\0*.tcfg\0\0";
std::string filter(filter_, filter_ + sizeof(filter_));
它看起来很糟糕,但希望你不会经常在你的代码中这样做。
更新:或者使用相应的begin()和end()模板定义(根据James Kanze的评论):
const char filter_[] = "Terrain Configuration (*.tcfg)\0*.tcfg\0\0";
std::string filter(begin(filter_), end(filter_));
答案 2 :(得分:2)
length()
string
是您需要使用的,以确保包含所有字符,只要它首先正确构造以包含嵌入的\0
字符。< / p>
LPCSTR
有效,而cString
在范围内:
#include <boost/scoped_array.hpp>
#include <string>
#include <algorithm>
string source("mystring");
boost::scoped_array<char> cString(new char[source.length() + 1]);
std::copy(source.begin(), source.end(), cString.get());
cString[source.length()] = 0;
LPCSTR rawStr = cString.get();
没有scoped_array:
#include <string>
#include <algorithm>
string source("mystring");
LPSTR rawStr = new char[source.length() + 1];
std::copy(source.begin(), source.end(), rawStr);
rawStr[source.length()] = 0;
// do the work here
delete[] rawStr;
编辑:
在filter
初始化版中,string
的构造函数仅包含第一个\0
字符的数据。这是有道理的 - 当它掌握的所有数据都是const char *
时,如何不停止复制数据呢?试试这个:
const char f3[] = "Terrain Configuration (*.tcfg)\0*.tcfg\0\0";
std::string filter(f3, sizeof(f3));
答案 3 :(得分:1)
这取决于std :: string的进一步生命周期。
例如,您可以手动追加终端零:
std::string test("init");
test += '\0';
这会导致长度增加一倍。或者只是创建另一个std :: string实例,并附加零