简体   繁体   English

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

[英]convert std::string to LPCSTR with trailing or leading '\0'

How can I convert std::string to LPCSTR while preserving '\\0' characters? 如何在保留'\\ 0'字符的同时将std :: string转换为LPCSTR?

I want to use the result on OPENFILENAME.lpstrFilter which requires the filter to contain '\\0' as delimiters. 我想在OPENFILENAME.lpstrFilter上使用结果,该结果要求过滤器包含'\\ 0'作为分隔符。

std::string.c_str() seems to strip and trim '\\0' std :: string.c_str()似乎剥离和修剪'\\ 0'

Thanks in advance! 提前致谢!

========================== ==========================

(How do I properly add a comment to the responses like a reply post in a forum?) (如何在论坛中正确添加评论,如回复帖?)

After reading your comments, I went on to double check this snippet: 看完你的评论后,我继续仔细检查这个片段:

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.
}

Am I mistaken on how c_str() or LPCSTR works? 我错误地认为c_str()或LPCSTR是如何工作的?

C_STR doesn't strip the NUL characters. C_STR不会删除NUL字符。 The error is likely in the way you are constructing the STD::string. 该错误可能与构造STD :: string的方式有关。

Generally speaking, std::string handles embedded '\\0' characters correctly. 一般来说,std :: string正确处理嵌入的'\\ 0'字符。

However, when interfacing with const char*, extreme care must be taken. 但是,当与const char *连接时,必须非常小心。

In this case, the problem already occurs during constructing the string with: 在这种情况下,在构造字符串期间已经出现问题:

std::string filter = "Terrain Configuration (*.tcfg)\0*.tcfg\0\0"; // wrong

Here you construct a std::string from a const char*. 在这里,您从const char *构造一个std :: string。 As the constructor doesn't know how many characters to use for constructing the std::string, it stops at the first '\\0'. 由于构造函数不知道用于构造std :: string的字符数,因此它会在第一个'\\ 0'处停止。

One could copy the characters one by one oneself, but there is a better way: use the contructor that requires two iterators to the char array, one with the begin and one with the end: 可以自己逐个复制字符,但有一种更好的方法:使用需要两个迭代器到char数组的构造函数,一个使用begin,另一个使用end:

const char filter_[] = "Terrain Configuration (*.tcfg)\0*.tcfg\0\0"; 
std::string filter(filter_, filter_ + sizeof(filter_));

It looks horrible, but hopefully you won't do this that frequently in your code. 它看起来很糟糕,但希望你不会经常在你的代码中这样做。

Update: Or with appropiate definitions of begin() and end() templates (as per James Kanze's comment): 更新:或者使用begin()和end()模板的适当定义(根据James Kanze的评论):

const char filter_[] = "Terrain Configuration (*.tcfg)\0*.tcfg\0\0"; 
std::string filter(begin(filter_), end(filter_));

The length() of your string is what you need to use to ensure all characters are included, provided it was properly constructed in the first place to include the embedded \\0 characters. 您需要使用stringlength()来确保包含所有字符,前提是它首先正确构造以包含嵌入的\\0字符。

For an LPCSTR valid while cString is in scope: 对于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();

Without scoped_array: 没有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;

EDIT: In your filter init, the constructor of string only includes data up to the first \\0 char. 编辑:在您的filter初始化中, string的构造函数仅包含第一个\\0字符的数据。 This makes sense - how else would it not to stop copying data when all it has in hand is const char * ? 这是有道理的 - 当它掌握的所有内容都是const char *时,如何不停止复制数据呢? Try this with: 试试这个:

const char f3[] = "Terrain Configuration (*.tcfg)\0*.tcfg\0\0";
std::string filter(f3, sizeof(f3));

It depends on further life-cycle of std::string. 它取决于std :: string的进一步生命周期。

For example you can append terminal zero manually: 例如,您可以手动追加终端零:

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

This causes length to be increased by one. 这导致长度增加1。 Or just create another instance of std::string with zero appended 或者只是创建另一个std :: string实例,并附加零

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM