我有一个字符串,
string str="aaa\0bbb";
我希望将此字符串的值复制到char *变量。我尝试了以下方法,但没有一个工作。
char *c=new char[7];
memcpy(c,&str[0],7); // c="aaa"
memcpy(c,str.data(),7); // c="aaa"
strcpy(c,str.data()); // c="aaa"
str.copy(c,7); // c="aaa"
如何在不丢失任何数据的情况下将该字符串复制到char *变量?
答案 0 :(得分:1)
您可以通过以下方式执行此操作
#include <iostream>
#include <string>
#include <cstring>
int main()
{
std::string s( "aaa\0bbb", 7 );
char *p = new char[s.size() + 1];
std::memcpy( p, s.c_str(), s.size() );
p[s.size()] = '\0';
size_t n = std::strlen( p );
std::cout << p << std::endl;
std::cout << p + n + 1 << std::endl;
}
程序输出
aaa
bbb
您需要在程序中的某处保留字符数组的已分配内存大小等于s.size() + 1
。
如果不需要将对象的“第二部分”保留为字符串,则可以分配大小为s.size()
的内存,而不是将其附加到终止零。
实际上你使用的这些方法
memcpy(c,&str[0],7); // c="aaa"
memcpy(c,str.data(),7); // c="aaa"
str.copy(c,7); // c="aaa"
是对的。它们只复制7个字符,前提是您不会将结果数组附加到终止零。问题是您尝试将结果字符数组输出为字符串,并且使用的运算符仅输出嵌入的零字符之前的字符。
答案 1 :(得分:0)
有两件事需要考虑:(1)确保str
已经包含完整的文字(仅使用char*
参数的构造函数可能会截断字符串终止符char)。 (2)如果str
实际上包含完整的文字,则语句memcpy(c,str.data(),7)
应该有效。唯一的问题是你如何看待&#34;结果,因为如果您将c
传递给printf
或cout
,那么一旦达到第一个字符串终止字符,它们就会停止打印。
因此:要确保将字符串文字"aaa\0bbb"
完全复制到str
,请使用std::string str("aaa\0bbb",7)
;然后,尝试在循环中打印c
的内容,例如:
std::string str("aaa\0bbb",7);
const char *c = str.data();
for (int i=0; i<7; i++) {
printf("%c", c[i] ? c[i] : '0');
}
答案 2 :(得分:0)
您的字符串由3个字符组成。您可以尝试使用
using namespace std::literals;
string str="aaa\0bbb"s;
使用\ 0创建字符串,它将包含7个字符
如果您将其用作c-string((const) char*
),它仍然无法提供帮助。 c-strings不能包含零字符。
答案 3 :(得分:-1)
你已经做过(不是真的,请看下面的编辑)。但问题是,无论你使用什么来打印字符串(printf
?),都使用结束字符串的c字符串约定为'\ 0'。所以它开始读取你的数据,但当它到达0
时,它会认为它已经完成(因为它没有别的办法)。
如果您只想将缓冲区写入输出,则必须使用
write(stdout, c, 7);
现在,write有关于数据结束位置的信息,因此它可以写入所有数据。
但请注意,您的终端无法真正显示\0
字符,因此它可能会显示一些奇怪的符号或根本不显示任何内容。如果你在linux上,你可以通过管道输入hexdump来查看二进制输出是什么。
编辑:
刚才意识到,你的字符串也会从const char*
开始通过阅读直到零。因此,您还必须使用构造函数来告诉它读过零:
std::string("data\0afterzero", 14);
(可能有更漂亮的解决方案)