为什么 C 中的字符串通常以 '\\0' 结尾?

新手上路,请多包涵

在许多代码示例中,人们通常在创建一个新的 char 数组后使用 '\0' 如下:

 string s = "JustAString";
char* array = new char[s.size() + 1];
strncpy(array, s.c_str(), s.size());
array[s.size()] = '\0';

为什么我们要在这里使用 '\0'

原文由 Kingfisher Phuoc 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.4k
2 个回答

您的问题标题引用了 C 字符串。 C++ std::string 对象的处理方式与 标准 C 字符串不同。 \0 在使用 C 字符串时很重要,当我在这个答案中使用术语 字符串 时,我指的是 _标准 C 字符串_。

\0 在 C 中充当字符串终止符。它被称为 _空字符_,或 NUL ,标准 C 字符串是以 _空结尾的_。这个终结符表示处理字符串的代码——标准库,还有你自己的代码——字符串的结尾在哪里。一个很好的例子是 strlen 它返回字符串的长度: strlen 工作的假设是它对使用 \0 终止的字符串进行操作。

当您声明一个常量字符串时:

 const char *str = "JustAString";

然后 \0 会自动为您附加。在其他情况下,您将像数组示例一样管理非常量字符串,有时您需要自己处理它。您的示例中使用 的 strncpy 的文档 是一个很好的说明: strncpy 复制空终止符, 除非 在复制整个字符串之前达到指定长度。因此,您会经常看到 strncpy可能冗余 的空终止符分配相结合。 strlcpystrcpy_s 旨在解决因忽视处理这种情况而产生的潜在问题。

In your particular example, array[s.size()] = '\0'; is one such redundancy: since array is of size s.size() + 1 , and strncpy is copying s.size() 字符,该函数将附加 \0

标准 C 字符串实用程序的文档将指出您何时需要小心包含此类空终止符。但请仔细阅读文档:与 strncpy 一样,细节很容易被忽视,导致潜在的缓冲区溢出。

原文由 pb2q 发布,翻译遵循 CC BY-SA 4.0 许可协议

strncpy(array, s.c_str(), s.size());
array[s.size()] = '\0';

为什么我们应该在这里使用’\0’?

你不应该,第二行是浪费空间。如果您知道如何使用它,strncpy 已经添加了一个空终止。代码可以重写为:

 strncpy(array, s.c_str(), s.size()+1);

strncpy 是一个奇怪的函数,它假设第一个参数是第三个参数大小的数组。因此,如果在复制字符串后还有剩余空间,它只会复制空终止。

在这种情况下,您也可以使用 memcpy(),它的效率会稍高一些,但可能会使代码阅读起来不那么直观。

原文由 Lundin 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题