Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么字符串是C++;通常以'结尾\0';?_C++_C_String - Fatal编程技术网

C++ 为什么字符串是C++;通常以'结尾\0';?

C++ 为什么字符串是C++;通常以'结尾\0';?,c++,c,string,C++,C,String,在许多代码示例中,人们通常在创建如下新字符数组后使用'\0': string s = "JustAString"; char* array = new char[s.size() + 1]; strncpy(array, s.c_str(), s.size()); array[s.size()] = '\0'; 为什么我们要在这里使用'\0' 问题的标题引用了C字符串。C++ >代码> STD::String 对象与标准C字符串不同。代码>\0在使用C字符串时非常重要,当我在这里使用术语str

在许多代码示例中,人们通常在创建如下新字符数组后使用
'\0'

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

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

问题的标题引用了C字符串。C++ >代码> STD::String 对象与标准C字符串不同。代码>\0在使用C字符串时非常重要,当我在这里使用术语
string
时,我指的是标准C字符串

\0
在C中充当字符串终止符。它被称为空字符或NUL。它向处理字符串的代码发出信号—标准库,但也包括您自己的代码—字符串的结尾在哪里。一个很好的例子是
strlen
,它返回字符串的长度

当您使用以下命令声明常量字符串时:

const char *str = "JustAString";
然后会自动为您添加
\0
。在其他情况下,您将管理一个非常量字符串,就像您的数组示例一样,您有时需要自己处理它。示例中使用的是一个很好的说明:
strncpy
复制空终止字符,除非在复制整个字符串之前达到指定长度。因此,您经常会看到
strncpy
与空终止符的可能冗余赋值相结合
strlcpy
strcpy_s
旨在解决因忽视处理此案例而产生的潜在问题

在您的特定示例中,
array[s.size()]='\0'
就是这样一种冗余:由于
数组
的大小为
s.size()+1
,并且
strncpy
正在复制
s.size()
字符,因此函数将追加
\0

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

<>强>为什么C++中的字符串通常以<代码> 0 \ < /代码>结束?< /强>

注意C++字符串和C字符串不相同。 在C++中,字符串引用<强> >强>这是一个模板类,并提供了许多直观的函数来处理字符串。 注意,C++ STD::string不是“代码> 0”/CODE终止,但类提供函数来获取基础字符串数据,如<代码> 0“/COD>终止的C风格字符串。

在C语言中,字符串是字符的集合。此集合通常以
\0
结尾
除非使用像
\0
这样的特殊字符,否则无法知道字符串何时结束。
它也被称为字符串空终止符

当然,也可能有其他簿记方法来跟踪字符串的长度,但使用特殊字符有两个直接的优点:

  • 它更直观、更直观
  • 没有额外的管理费用
请注意,之所以需要
\0
,是因为大多数标准C库函数都是在字符串上运行的,假定它们是
\0
终止的。
例如:
使用
printf()
时,如果您有一个字符串未被
\0
终止,那么
printf()
会一直向
stdout
写入字符,直到遇到
\0
为止,简而言之,它甚至可能会打印垃圾

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

当您不需要终止字符串时,有两种情况:

  • 在任何用法中,如果您明确地将字符串的长度和
  • 如果您使用的是一些标准库api,则会在字符串中隐式添加一个
    \0
在您的情况下,您已经有了第二个场景

array[s.size()] = '\0';
在您的示例中,上面的代码语句是多余的


例如,使用
strncpy()
strncpy()
s.size()
字符复制到
数组中
,请注意,如果复制字符串后剩余空间,则会附加空终止符。由于
数组
的大小为
s,因此会自动添加
\0

“\0”是空终止字符。如果您的字符数组没有它,而您尝试执行strcpy,则会出现缓冲区溢出。许多函数依赖它来知道何时需要停止读取或写入内存

在C中,我们用字符数组(或w_char)表示字符串,并使用特殊字符来表示字符串的结尾。与Pascal相反,Pascal将字符串的长度存储在数组的索引0中(因此字符串对字符数有一个硬限制),理论上对字符串(表示为字符数组)在C中可以具有的字符数没有限制

在C中的默认库以及其他库中的所有函数中,特殊字符都应该是NUL。如果要使用依赖于字符串精确长度的库函数,则必须使用NUL终止字符串。您可以完全定义自己的终止字符,但必须了解涉及字符串(作为字符数组)的库函数可能无法按预期工作,并且会导致各种错误

在给定的代码片段中,需要显式地将终止字符设置为NUL,因为您不知道分配的数组中是否有垃圾数据。这也是一个很好的实践,因为在大型代码中,您可能看不到字符数组的初始化

strncpy(array, s.c_str(), s.size());
array[s.size()] = '\0';
为什么要在这里使用“\0”

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

strncpy(array, s.c_str(), s.size()+1);
strncpy有点奇怪