【问题标题】:What should we use as the second argument of std::strcpy?我们应该使用什么作为 std::strcpy 的第二个参数?
【发布时间】:2013-04-03 08:05:29
【问题描述】:

我有以下示例,取自这里:

// strings and c-strings
#include <iostream>
#include <cstring>
#include <string>

int main ()
{
  std::string str ("Please split this sentence into tokens");

  char * cstr = new char [str.length()+1];
  std::strcpy (cstr, str.c_str());

  // cstr now contains a c-string copy of str

  char * p = std::strtok (cstr," ");
  while (p!=0)
  {
    std::cout << p << '\n';
    p = strtok(NULL," ");
  }

  delete[] cstr;
  return 0;
}

据我了解str 是一个字符串,str.c_str() 是一个指针,指向包含str 字符作为其元素的数组的第一个元素。然后使用std::strcpy,我们将给定地址的值作为其第二个参数,并将该值分配给作为第一个参数(cstr)给出的指针。

但是,我有以下示例,取自here

#include <iostream>
#include <cstring>

int main()
{
    char *str = new char[100];
    std::strcpy(str, "I am string!");
    std::cout << str;
    delete[] str;
}

现在作为第二个参数,我们有一个字符串(而不是第一个示例中的指向数组的指针)。

请任何人澄清这种不一致之处吗?

【问题讨论】:

  • 澄清一下:"..." 被称为字符串文字,它不是 std::string。您可能会感到困惑,因为std::string 有一个允许从字符指针进行隐式转换的构造函数,即std::string(char const* str)
  • 仅作记录:strtok 不应在您必须维护的代码中使用。 (它是像 gets 这样的函数之一,由于历史原因而存在,但不应在新代码中使用。)
  • @Pubby,但是为什么我们在第二个例子中使用“字符串文字”作为std::strcpy 的第二个参数,我们不需要使用指针作为第二个参数(其值将传递给std::strcpy)的第一个参数?
  • @Roman 因为字符串文字可以隐式转换为char const*。您希望它看起来如何?
  • @Pubby,感谢您的澄清。我不知道"..."被解释为char const*,我认为它只是string类型的值,我们需要将它分配给一个变量(例如x)并且使用&amp;x作为std::strcpy 的第二个参数来传递地址。但正如我从你那里了解到的,"..." 已经是一个地址(老实说,这是一个违反直觉的想法)。例如,您会期望 2 只是一个整数值,而不是指针(它只是一个值,而不是指针)。但是,相比之下,“abs”不是一个值,它已经是一个指向数组的指针。

标签: c++ pointers std strcpy


【解决方案1】:

当使用 std::strcpy 时,我们将给定地址的值作为它的 第二个参数并将此值分配给给出的指针 第一个参数 (cstr)。

char * strcpy ( char * destination, const char * source );

没有 strcpy 实际读取 source 指向的每个字符并将它们写入目标,它在读取终止空字符时停止。

在您的第二个示例中,您的源参数是字符串文字,其类型为 const char[]。该字符串可以衰减为 const char* 以传递给 strcpy。

字符串文字只不过是指向只读位置的指针。

【讨论】:

  • 是的,我看到了引用的解释,这个解释和我的第一个例子是一致的。然而,在第二个例子中,我们使用字符串作为第二个参数,而不是一个值是地址的指针。
  • 正如 ForEver 所说,字符串文字是 const char[],因此可以衰减为 const char*。它也是一个指向只读位置的指针。
  • 不,“我是字符串!”也是一个指向(未命名的)char 数组的指针。
【解决方案2】:
std::strcpy(str, "I am string!");

“我是字符串!”

是字符串字面量。真的是const char[13](传入函数时衰减到const char*)。

n3376 2.14.5/8

普通字符串文字和 UTF-8 字符串文字也称为窄字符串文字。一个箭头 字符串字面量的类型为“array of n const char”,其中 n 是字符串的大小,定义如下,并且具有 静态存储持续时间 (3.7)。

n3376 4.2/1 隐式数组到指针的转换。

“N T 数组”或“T 的未知边界数组”类型的左值或右值可以转换为纯右值 类型为“指向 T 的指针”。结果是指向数组第一个元素的指针。

【讨论】:

  • 你应该提到字符数组正在衰减到这里的指针。
【解决方案3】:

char *strcpy( char *dest, const char *src ); 需要 const char 的源指针,并将内存复制到 char 类型的目标指针。该函数从源复制字符串长度,直到找到以空字符结尾的源字符串。 "I am string!" 是一个 const char* const` 是一个字符串文字,主要存储在只读标记的内存中。

【讨论】:

    【解决方案4】:

    现在作为第二个参数,我们有一个字符串(而不是像第一个示例中那样指向数组的指针)

    在第二个示例中,您有一个 C 字符串,它是一个指向以 NUL 结尾的字符数组的指针。没有不一致的地方。

    【讨论】:

    • 在第二个例子中,第二个参数是“我是字符串!”,它只是一个字符串(正如它的值所说的那样)。它不是 C 字符串。要获取 C 字符串,我们需要对其应用 c_str() 函数。
    • @Roman:它一个C字符串,你不能对它应用.c_str()(试试看!)
    猜你喜欢
    • 2021-06-19
    • 1970-01-01
    • 2013-09-29
    • 1970-01-01
    • 2018-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多