我有一个已知长度的字符数组,带有嵌入的空值;没有结束null。
const char * raw = "text1\0\0text2\0\0\0text3\0more text";
这样做
std::string clean(raw);
只给我第一个字符串("text1"
)但是,我想要整个原始字符串。
我想要多个字符串。在这种特殊情况下,raw.
答案 0 :(得分:4)
如果您可以将raw
的类型从const char *
更改为const char[]
,那么您可以使用一对迭代器构造字符串
const char raw[] = "text1\0\0text2\0\0\0text3\0more text";
std::string clean(std::begin(raw), std::end(raw));
否则,您需要向std::string
构造函数提供字符串文字的长度。
std::string clean(raw, length);
要回答有关如何从字符串文字中提取4个空字符分隔字符串的已编辑问题,这里有一个循环,可以完成这项工作
std::vector<std::string> tokens;
std::string::size_type pos, lastPos = 0;
while(pos < clean.length())
{
// find next delimiter
pos = clean.find_first_of('\0', lastPos);
if(pos == std::string::npos) {
// we've reached the end of the string, so get remaining
pos = clean.length();
}
// if not empty add it to the vector
if(pos != lastPos) tokens.push_back(clean.substr(lastPos, pos - lastPos));
// increment to next character
lastPos = pos + 1;
}
答案 1 :(得分:4)
在不知道字符串文字的实际大小的情况下,您将无法完成任务。 如果你知道大小,那么你可以使用构造函数
basic_string(const charT* s, size_type n, const Allocator& a = Allocator());
或相应的方法assign
这里第二个参数指定将在字符串中复制的s的字符数。
如果知道长度,那么你可以简单地写
std::string clean( raw, n );
或
std::string clean;
clean.assign( raw, n );
编辑:当您更改原始邮件时,我会附上我的帖子。您可以通过以下方式拆分文字
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
int main()
{
const char * s = "text1\0\0text2\0\0\0text3\0more text";
size_t n = 30;
std::istringstream is( std::string( s, 30 ) );
std::vector<std::string> v;
std::string word;
while ( std::getline( is, word, '\0' ) ) if ( !word.empty() ) v.push_back( word );
for ( const std::string &s : v ) std::cout << s << std::endl;
}
输出
text1
text2
text3
more text
如果你有四个不同的字符串,你可以写
#include <iostream>
#include <sstream>
#include <string>
int main()
{
const char * s = "text1\0\0text2\0\0\0text3\0more text";
size_t n = 30;
std::istringstream is( std::string( s, 30 ) );
std::string word1, word2, word3, word4;
while ( std::getline( is, word1, '\0' ) && word1.empty() );
while ( std::getline( is, word2, '\0' ) && word2.empty() );
while ( std::getline( is, word3, '\0' ) && word3.empty() );
while ( std::getline( is, word4, '\0' ) && word4.empty() );
for ( const std::string &s : { word1, word2, word3, word4 } ) std::cout << s << std::endl;
}
答案 2 :(得分:2)
std::string
有一个constructor,需要const char *
和一个计数。您必须确定要复制的字符串中有多少个字符,因为您不能使用通常的空终止符约定。
答案 3 :(得分:1)
因为没有结尾null,你必须以其他方式知道大小。
根据已知尺寸,只需使用the string constructor that takes a pointer to first char, and a size。
std::string
可以包含空值。
答案 4 :(得分:1)
你可以去:
std::string(clean, clean + 30);
如果将字符串存储在数组(或#define
)中会更好,然后您可以通过编程方式检查其长度,例如
char const raw[] = "text1\0\0text2\0\0\0text3\0more text";
std::string(raw, raw + sizeof raw - 1);
答案 5 :(得分:0)
这是预期的行为。 &#34; \ 0&#34;被理解为字符串的结尾。如果你试图使用&#34;%s&#34;来修改原始变量。格式你会得到相同的输出 - &#34; text1&#34;。如果你想要整个字符串,这就是你应该做的:
const char * raw = "text1\\0\\0text2\\0\\0\\0text3\\0more text";
因此,在将它传递给std :: string构造函数之前,您可以编写另一个附加额外&#39; \&#39;。
的例程。