10

我已经做了一些基本的阅读,并且从我收集的内容中 .c_str() 总是有一个空终止符。

我有一个相当简单的 C++ 程序:

int main(int argc, char** argv)
{
  std::string from = "hello";
  char to[20];
  memcpy(to, from.c_str(), strlen(from.c_str())+1);
  std::cout<< to << std::endl;
  return 0;
}

该 memcpy 是否会确保我将一个以 null 结尾的字符串复制到我的变量中(假设我的字符串 from 的长度较短)?

4

4 回答 4

7

您应该使用std::string来复制字符串。但是,如果你想这样做,你应该使用strcpy而不是memcpy

int main(int argc, char** argv)
{
  std::string from = "hello";
  char to[20];
  strcpy(to, from.c_str());
  std::cout<< to << std::endl;
  return 0;
}
于 2013-07-11T07:39:11.827 回答
5

memcpy不知道什么是字符串。你给它一个复制的范围。它取决于strlen此处提供范围的终止点

于 2013-07-11T06:55:38.010 回答
2

是的,只要您的字符串 infrom短于 20,这将起作用。哦,不,等等,我们也在复制 NULL 终止符,因此它必须短于 19。我想您知道这会导致一些混乱。

顺便说一句,这正是这段代码危险的原因:我假设这是演示代码,而您的实际代码将从某种输入中获取该字符串。在那一刻,你将无法控制它有多长。您可以截断它,但您可能会忘记这样做,这意味着您的程序会将内容复制到可能不属于它的内存中。这可能会导致崩溃,但至少会导致未定义的行为,因为您正在覆盖可能包含其他重要数据的内存。

使用string类实际上有助于避免此类问题,因为不必指定字符串长度。我建议使用这个类,并且只c_str()在绝对必要时进行操作。

于 2013-07-11T06:50:59.827 回答
0

你的问题的答案是“是”(只要你的 char 数组足够大,你应该放一个验证步骤)。

如果你真的想这样做,你可以这样做:

int main(int argc, char** argv)
{
  std::string from = "hello";
  char* to = new char[from.length() + 1];
  strcpy(to, from.c_str()); ///Or memcpy(to, from.c_str(), from.length() + 1 );
  std::cout<< to << std::endl;
  delete[] to;
  return 0;
}

只要您不将另一个更长的字符串写入“to”,哪个更安全

于 2013-07-11T07:11:26.643 回答