2

如何在保留 '\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

4 回答 4

6

C_STR 不会去除 NUL 字符。该错误可能与您构建 STD::string 的方式有关。

于 2010-10-08T13:51:31.883 回答
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 数组的构造函数,一个带有开头,一个带有结尾:

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_));
于 2010-10-08T14:48:26.517 回答
2

您的length()of yourstring是您需要用来确保包含所有字符的内容,前提是它首先正确构建以包含嵌入的\0字符。

对于LPCSTR有效的 whilecString在范围内:

#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;

编辑:在您的filterinit 中,构造函数string仅包含直到第一个\0字符的数据。这是有道理的——当手头只有数据时,它怎么能不停止复制数据const char *呢?试试这个:

const char f3[] = "Terrain Configuration (*.tcfg)\0*.tcfg\0\0";
std::string filter(f3, sizeof(f3));
于 2010-10-08T13:53:05.847 回答
1

这取决于 std::string 的进一步生命周期。

例如,您可以手动附加终端零:

std::string test("init");
test += '\0';

这导致长度增加一。或者只是创建另一个附加零的 std::string 实例

于 2010-10-08T13:49:48.333 回答