Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/150.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何从嵌入空值的字符数组中提取std::string_C++ - Fatal编程技术网

C++ 如何从嵌入空值的字符数组中提取std::string

C++ 如何从嵌入空值的字符数组中提取std::string,c++,C++,我有一个已知长度的字符数组,带有嵌入的空值;没有结尾空 const char * raw = "text1\0\0text2\0\0\0text3\0more text"; 这样做 std::string clean(raw); 只给我第一个字符串(“text1”),但是,我需要整个原始字符串 我想要多个字符串。在这种特殊情况下,原始数据中有4个字符串。因为没有结尾null,所以您必须以其他方式知道大小 给定已知的大小,只需使用 std::string可以包含空值。std::string具有

我有一个已知长度的字符数组,带有嵌入的空值;没有结尾空

const char * raw = "text1\0\0text2\0\0\0text3\0more text";
这样做

std::string clean(raw);
只给我第一个字符串(
“text1”
),但是,我需要整个原始字符串


我想要多个字符串。在这种特殊情况下,原始数据中有4个字符串。

因为没有结尾null,所以您必须以其他方式知道大小

给定已知的大小,只需使用


std::string
可以包含空值。

std::string
具有接受
常量字符*
和计数的。您必须确定要复制的字符串中有多少个字符,因为您不能使用空终止符的常规约定。

如果您可以将
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;
}
std::向量令牌;
std::string::size\u type pos,lastPos=0;
而(位置

如果不知道字符串文字的实际大小,您将不会执行此任务。 如果您知道大小,那么可以使用构造函数

basic_string(const charT* s, size_type n, const Allocator& a = Allocator());
或相应的方法
assign

这里,第二个参数指定将在字符串中复制的字符数

如果长度是已知的,那么你可以简单地写

std::string clean( 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;
}
如果你有四个不同的字符串,你可以写

#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;
}
#包括
#包括
#包括
int main()
{
const char*s=“text1\0\0text2\0\0\0text3\0更多文本”;
尺寸n=30;
std::istringstream是(std::string(s,30));
std::字符串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());

对于(const std::string&s:{word1,word2,word3,word4})std::cout这是预期的行为。将“\0”理解为字符串的结尾。如果您尝试使用“%s”格式优先处理原始变量,您将得到相同的输出-“text1”。如果您想要整个字符串,您应该这样做:

const char * raw = "text1\\0\\0text2\\0\\0\\0text3\\0more text";
因此,在将其传递给std::string构造函数之前,您可以编写另一个附加额外“\”的例程。

您可以:

std::string(clean, clean + 30);
如果将字符串存储在数组(或
#define
)中,则可以通过编程方式检查其长度,例如

char const raw[] = "text1\0\0text2\0\0\0text3\0more text";
std::string(raw, raw + sizeof raw - 1);


这会将字符串更改为不包含嵌入的空值,我不认为这是他想要的。那么也许他应该将其存储在std::stringstream中?我不知道。为什么没有结尾空值?它就在那里,在结尾处…@KerrekSB:对于嵌入的空值,在结尾处自动添加一个空值,而不是结尾空值。因为它不能ot可用于检测结束。此类字符串的结束null(我认为Vlad的意思是)是程序员放置在末尾的null,后跟自动生成的null。哦,不是“Vlad”,而是“user841550”或“the OP”。抱歉。此外,我发布了错误的代码。现在返回。Coffee.+1,因为这似乎是唯一合理的答案:-)这给了我一个字符串。我希望分别提取每个字符串。@user841550:那是因为你写了一个非常不清楚的问题。你为什么不说出你真正想要的?@user841550所有人,包括我在内elf,我想让它们都是指你想要整个字符串文本在一个
std::string
中。所以你想要4个
std::string
对象?@Praetorian。是的,我想要所有单个字符串对象嵌入到array@KerrekSB关于我在“构造函数”一词中给出的链接的脚注4。不要只是对问题进行越来越多的更正-重写它,使其成为一个单一、简洁、清晰的问题。@user841550请参阅我的更新帖子。@Kerrek SB我认为std::string(s)在标题中会很清楚,但我想不是。但是我也说我的尝试给了我一个字符串,我想要它们。另外,考虑使用<代码>向量< /代码>,因为这不是一个真正的字符串。你能告诉我如何分别提取4个字符串吗?这是我想要的最接近的字符串。far@user841550请参阅我的更新帖子。我更喜欢你的第一个版本,因为数组中字符串的计数可能未知。我正在尝试确定您的解决方案与Praetorian在以下方面的比较:efficiency@user841550当前位置不要为小事烦恼。
std::string(clean, clean + 30);
char const raw[] = "text1\0\0text2\0\0\0text3\0more text";
std::string(raw, raw + sizeof raw - 1);