将std :: string转换为LPCSTR,尾随或前导'\ 0'

时间:2010-10-08 13:45:29

标签: c++ stdstring lpcstr

如何在保留'\ 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的工作原理?

4 个答案:

答案 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实例,并附加零