为什么 C++ 中的字符串通常以“\0”结尾?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10943033/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why are strings in C++ usually terminated with '\0'?
提问by Kingfisher Phuoc
In many code samples, people usually use '\0'
after creating a new char array like this:
在许多代码示例中,人们通常'\0'
在创建一个新的 char 数组后使用,如下所示:
string s = "JustAString";
char* array = new char[s.size() + 1];
strncpy(array, s.c_str(), s.size());
array[s.size()] = 'const char *str = "JustAString";
';
Why should we use '\0'
here?
为什么要'\0'
在这里使用?
回答by pb2q
The title of your question references C strings. C++ std::string
objects are handled differently than standard Cstrings. \0
is important when using C strings, and when I use the term string
here, I'm referring to standard C strings.
您的问题的标题引用了 C 字符串。C++std::string
对象的处理方式与标准 C字符串不同。\0
使用 C 字符串时很重要,当我在string
这里使用该术语时,我指的是标准 C 字符串。
\0
acts as a string terminator in C. It is known as the null character, or NUL. It signals code that processes strings - standard libraries but also your own code - where the end of a string is. A good example is strlen
which returns the length of a string.
\0
在 C 中充当字符串终止符。它被称为空字符或NUL。它表示处理字符串的代码 - 标准库以及您自己的代码 - 字符串的结尾在哪里。一个很好的例子是strlen
它返回字符串的长度。
When you declare a constant string with:
当你声明一个常量字符串时:
array[s.size()] = 'strncpy(array, s.c_str(), s.size());
array[s.size()] = 'strncpy(array, s.c_str(), s.size()+1);
';
';
then the \0
is appended automatically for you. In other cases, where you'll be managing a non-constant string as with your array example, you'll sometimes need to deal with it yourself. The docs for strncpy, which is used in your example, are a good illustration: strncpy
copies over the null termination characters exceptin the case where the specified length is reached before the entire string is copied. Hence you'll often see strncpy
combined with the possibly redundantassignment of a null terminator. strlcpy
and strcpy_s
were designed to address the potential problems that arise from neglecting to handle this case.
然后\0
会自动为您附加。在其他情况下,您将像数组示例一样管理非常量字符串,有时您需要自己处理它。该对函数strncpy文档,这是在实施例中使用,是一个很好的例子:strncpy
在空终止字符拷贝除了在整个字符串被复制之前达到指定的长度的情况。因此,您经常会看到strncpy
与空终止符的可能冗余分配相结合。strlcpy
并strcpy_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()
characters, the function will append the \0
.
在您的特定示例中,array[s.size()] = '\0';
就是这样一种冗余:由于array
是 sizes.size() + 1
并且strncpy
正在复制s.size()
字符,因此该函数将附加\0
.
The documentation for standard C string utilities will indicate when you'll need to be careful to include such a null terminator. But read the documentation carefully: as with strncpy
the details are easily overlooked, leading to potential buffer overflows.
标准 C 字符串实用程序的文档将指示您何时需要小心包含此类空终止符。但是请仔细阅读文档:因为strncpy
细节很容易被忽视,导致潜在的缓冲区溢出。
回答by Alok Save
Why are strings in C++ usually terminated with
'\0'
?
为什么 C++ 中的字符串通常以
'\0'
?
Note that C++ Strings and C strings are not the same.
In C++ string refers to std::stringwhich is a template class and provides a lot of intuitive functions to handle the string.
Note that C++ std::string are not \0
terminated, but the class provides functions to fetch the underlying string data as \0
terminated c-style string.
请注意,C++ 字符串和 C 字符串并不相同。
在 C++ 中,字符串指的是std::string,它是一个模板类,提供了很多直观的函数来处理字符串。
请注意,C++ std::string 并未\0
终止,但该类提供了将底层字符串数据作为\0
终止的 c 样式字符串获取的函数。
In C a string is collection of characters. This collection usually ends with a \0
.
Unless a special character like \0
is used there would be no way of knowing when a string ends.
It is also aptly known as the string null terminator.
在 C 中,字符串是字符的集合。此集合通常以\0
.
除非使用像这样的特殊字符,否则\0
无法知道字符串何时结束。
它也被恰当地称为字符串空终止符。
Ofcourse, there could be other ways of bookkeeping to track the length of the string, but using a special character has two straight advantages:
当然,可能还有其他的簿记方式来跟踪字符串的长度,但使用特殊字符有两个直接的优点:
- It is more intuitive and
- There are no additional overheads
- 它更直观和
- 没有额外的开销
Note that \0
is needed because most of Standard C library functions operate on strings assuming they are \0
terminated.
For example:
While using printf()
if you have an string which is not \0
terminated then printf()
keeps writing characters to stdout
until a \0
is encountered, in short it might even print garbage.
请注意,这\0
是必需的,因为大多数标准 C 库函数都在假设字符串已\0
终止的情况下对字符串进行操作。
例如:
在使用时,printf()
如果您有一个未\0
终止的字符串,则printf()
继续写入字符,stdout
直到\0
遇到a 为止,简而言之,它甚至可能会打印垃圾。
Why should we use
'\0'
here?
为什么要
'\0'
在这里使用?
There are two scenarios when you do not need to \0
terminate a string:
当您不需要\0
终止字符串时,有两种情况:
- In any usage if you are explicitly bookkeeping length of the string and
- If you are using some standard library api will implicitly add a
\0
to strings.
- 在任何用法中,如果您明确记录字符串的长度和
- 如果你正在使用一些标准库 api 会隐式地添加一个
\0
到字符串。
In your case you already have the second scenario working for you.
在您的情况下,您已经有第二种方案适合您。
##代码##The above code statement is redundant in your example.
上面的代码语句在您的示例中是多余的。
For your example using strncpy()
makes it useless. strncpy()
copies s.size()
characters to your array
, Note that it appends a null termination if there is any space left after copying the strings. Since array
is of size s.size() + 1
a \0
is automagically added.
对于您的示例,使用strncpy()
使其无用。strncpy()
将s.size()
字符复制到您的array
,请注意,如果复制字符串后还有剩余空间,它会附加一个空终止符。由于array
大小为s.size() + 1
a\0
是自动添加的。
回答by evanmcdonnal
'\0' is the null termination character. If your character array didn't have it and you tried to do a strcpy you would have a buffer overflow. Many functions rely on it to know when they need to stop reading or writing memory.
'\0' 是空终止符。如果您的字符数组没有它并且您尝试执行 strcpy ,则会出现缓冲区溢出。许多函数依靠它来知道何时需要停止读取或写入内存。
回答by Lundin
Why should we use '\0' here?
为什么要在这里使用'\0'?
You shouldn't, that second line is waste of space. strncpy already adds a null termination if you know how to use it. The code can be rewritten as:
你不应该,第二行是浪费空间。如果您知道如何使用 strncpy 已经添加了一个空终止。代码可以改写为:
##代码##strncpy is sort of a weird function, it assumes that the first parameter is an array of the size of the third parameter. So it only copies null termination if there is any space left after copying the strings.
strncpy 是一个奇怪的函数,它假设第一个参数是第三个参数大小的数组。因此,如果复制字符串后还有剩余空间,它只会复制空终止。
You could also have used memcpy() in this case, it will be slightly more efficient, though perhaps makes the code less intuitive to read.
在这种情况下,您也可以使用 memcpy(),它会稍微高效一些,但可能会使代码不那么直观。
回答by nhahtdh
In C, we represent string with an array of char (or w_char), and use special character to signal the end of the string. As opposed to Pascal, which stores the length of the string in the index 0 of the array (thus the string has a hard limit on the number of characters), there is theoreticallyno limit on the number of characters that a string (represented as array of characters) can have in C.
在 C 中,我们用一个 char(或 w_char)数组表示字符串,并使用特殊字符来表示字符串的结束。与 Pascal 不同,Pascal 将字符串的长度存储在数组的索引 0 中(因此字符串对字符数有硬性限制),理论上对字符串的字符数没有限制(表示为字符数组)在 C 中可以有。
The special character is expected to be NUL in all the functions from the default library in C, and also other libraries. If you want to use the library functions that relies on the exact length of the string, you must terminate the string with NUL. You can totally define your own terminating character, but you must understand that library functions involving string (as array of characters) may not work as you expect and it will cause all sorts of errors.
在 C 中默认库以及其他库的所有函数中,特殊字符应为 NUL。如果要使用依赖于字符串确切长度的库函数,则必须使用 NUL 终止字符串。您可以完全定义自己的终止字符,但您必须了解涉及字符串(作为字符数组)的库函数可能无法按您的预期工作,并且会导致各种错误。
In the snippet of code given, there is a need to explicitly set the terminating character to NUL, since you don't know if there are trash data in the array allocated. It is also a good practice, since in large code, you may not see the initialization of the array of characters.
在给出的代码片段中,需要将终止字符显式设置为 NUL,因为您不知道分配的数组中是否有垃圾数据。这也是一种很好的做法,因为在大型代码中,您可能看不到字符数组的初始化。