在许多代码示例中,人们通常在创建一个新的 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 许可协议
在许多代码示例中,人们通常在创建一个新的 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 许可协议
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 许可协议
3 回答2k 阅读✓ 已解决
2 回答3.9k 阅读✓ 已解决
2 回答3.2k 阅读✓ 已解决
1 回答3.2k 阅读✓ 已解决
1 回答2.7k 阅读✓ 已解决
3 回答3.4k 阅读
1 回答2.7k 阅读✓ 已解决
您的问题标题引用了 C 字符串。 C++
std::string
对象的处理方式与 标准 C 字符串不同。\0
在使用 C 字符串时很重要,当我在这个答案中使用术语 字符串 时,我指的是 _标准 C 字符串_。\0
在 C 中充当字符串终止符。它被称为 _空字符_,或 NUL ,标准 C 字符串是以 _空结尾的_。这个终结符表示处理字符串的代码——标准库,还有你自己的代码——字符串的结尾在哪里。一个很好的例子是strlen
它返回字符串的长度:strlen
工作的假设是它对使用\0
终止的字符串进行操作。当您声明一个常量字符串时:
然后
\0
会自动为您附加。在其他情况下,您将像数组示例一样管理非常量字符串,有时您需要自己处理它。您的示例中使用 的 strncpy 的文档 是一个很好的说明:strncpy
复制空终止符, 除非 在复制整个字符串之前达到指定长度。因此,您会经常看到strncpy
与 可能冗余 的空终止符分配相结合。strlcpy
和strcpy_s
旨在解决因忽视处理这种情况而产生的潜在问题。In your particular example,
array[s.size()] = '\0';
is one such redundancy: sincearray
is of sizes.size() + 1
, andstrncpy
is copyings.size()
字符,该函数将附加\0
。标准 C 字符串实用程序的文档将指出您何时需要小心包含此类空终止符。但请仔细阅读文档:与
strncpy
一样,细节很容易被忽视,导致潜在的缓冲区溢出。