阅读背景:

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

来源:互联网 

In many code samples, people usually use '

In many code samples, people usually use '\0' after creating a new char array like this:

在许多代码示例中,人们通常在创建这样的新char数组之后使用'\0:

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

Why should we use '\0' here?

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

5 个解决方案

#1


41  

The title of your question references C strings. C++ std::string objects are handled differently than standard C strings. \0 is important when using C strings, and when I use the term string here, I'm referring to standard C strings.

问题的标题引用了C字符串。:字符串对象的处理方式与标准的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:

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

const char *str = "JustAString";

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 except in the case where the specified length is reached before the entire string is copied. Hence you'll often see strncpy combined with the possibly redundant assignment 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复制了null终止字符,但是在复制整个字符串之前达到指定长度的情况除外。因此,您经常会看到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';是这样的冗余:因为数组的大小是s.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一样,细节很容易被忽略,从而导致潜在的缓冲区溢出。

#2


13  

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::string which 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++ string中指的是std::string,它是一个模板类,提供了很多处理字符串的直观函数。注意,C++ std::string不是终止的\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 \0terminated 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,简而言之,它甚至可能打印垃圾。

Why should we use '\0' here?

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

There are two scenarios when you do not need to \0 terminate a string:

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

  • 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.

在你的例子中,你已经有了第二个方案。

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

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 arrayis of size s.size() + 1 a \0 is automagically added.

对于您的示例,使用strncpy()会使它变得无用。strncpy()将.size()字符复制到您的数组中,请注意,如果在复制字符串之后还剩下任何空间,它将附加一个空终止符。由于arrayis的大小是s.size() + 1,所以自动添加了一个\0。

#3


6  

'\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,那么您将会有一个缓冲区溢出。许多函数都依赖它来知道何时需要停止读或写内存。

#4


3  

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

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(array, s.c_str(), s.size()+1);

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(),它会稍微提高效率,尽管这可能会降低代码的可读性。

#5


2  

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 theoretically no limit on the number of characters that a string (represented as array of characters) can have in C.

在C中,我们用char(或w_char)数组表示字符串,并使用特殊字符来表示字符串的末尾。而不是帕斯卡,字符串的长度存储在数组的索引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,因为您不知道在分配的数组中是否存在垃圾数据。这也是一个很好的实践,因为在大型代码中,您可能看不到字符数组的初始化。


'
after creating a new char array like this: a




你的当前访问异常,请进行认证后继续阅读剩余内容。

分享到: