9.4 Length-Restricted String Functions
The library includes several functions that deal with strings in a different way. This group of functions takes an explicit length argument that limits how many characters can be copied or compared. These functions provide an easy mechanism to prevent unexpectedly long strings from overflowing their destinations.
标准库还包含了一些函数,它们以一种不同的方式处理字符串。这些函数接受一个显式的长度参数,用于限定进行复制或比较的字符数。这些函数提供了一种方便的机制,可以防止难以预料的长字符串从它们的目标数组溢出。
The prototypes for these functions are shown on the next page. Like their unrestricted cousins, the results from strncpy and strncat are undefined if the source and destination arguments overlap.
这些函数的原型如下所示。和它们的不受限制版本一样,如果源参数和目标参数发生重叠,strncpy 和strncat 的结果就是未定义的。
char *strncpy( char *dst, char const *src, size_t len );
char *strncat( char *dst, char const *src, size_t len );
int strncmp( char const *s1, char const *s2, size_t len );
Like strcpy, strncpy copies characters from the source string to the destination array.However, it always writes exactly len characters to dst. If strlen( src ) is less than len, then dst is padded to a length of len with additional NUL characters. If strlen(src ) is greater than or equal to len, then only len characters will be written to dst,and the result will not be NUL‐terminated!
和strcpy 一样, strncpy 把源字符串的字符复制到目标数组。然而,它总是正好向dst 写入len个字符。如果strlen( src )的值小于len , dst 数组就用额外的NUL 字节填充到len 长度。如果strlen( src)的值大于或等于len ,那么只有len 个字符被复制到dst 中。注意!它的结果将不会以NUL 字节结尾。
The result of a call to strncpy might not be a string, because strings must be terminated with a NUL byte. What happens if an unterminated sequence of characters is used where a string is required, for example, as an argument to strlen? The function will be unable to tell that the NUL is missing, so it will continue looking,character by character, until it finds one. It might not find one until hundreds of characters later, and the value returned by strlen will essentially be a random number. Or, the program might crash trying to access memory beyond what was allocated to it.
strncpy 调用的结果可能不是一个字符串,因此字符串必须以NUL字节结尾。如果在一个需要字符串的地方(例如strlen 函数的参数)使用了一个不是以NUL 字节结尾的字符序列,会发生什么情况呢? strlen 函数将无法知道NUL 字节是没有的,所以它将继续进行查找,一个字符接一个字符,直到它发现一个NUL 字节为止。或许它找了几百个字符才找到,而strlen 函数的这个返回值从本质上说是一个随机数。或者,如果函数试图访问系统分配给这个程序以外的内存范围,程序就会崩溃。
This problem only occurs when you create strings with the strncpy function, and then either use them with the str--- functions or print them with the %s format code of printf. Before using the unrestricted functions, you must first ensure that the string is actually NUL‐terminated. For example, consider this code fragment:
这个问题只有当你使用strncpy 函数创建字符串,然后或者对它们使用str开头的库函数,或者在printf 中使用%s 格式码打印它们时才会发生。在使用不受限制的函数之前,你首先必须确定字符串实际上是以NUL 字节结尾的。例如,考虑下面这个代码段:
char buffer[BSIZE];
...
strncpy( buffer, name, BSIZE );
buffer[BSIZE – 1] = '\0';
If the contents of name fit into buffer, the assignment has no effect. If name is too long,though, the assignment ensures that the string in buffer is properly terminated.Subsequent calls to strlen or other unrestricted string functions on this array will work properly.
如采name 的内容可以容纳于buffer 中,最后那个赋值语句没有任何效果。但是,如果name 太长,这条赋值语句可以保证buffer 中的字符串是以NUL 结尾的。以后对这个数组使用strlen 或其他不受限制的字符串函数将能够正确工作。
Although strncat is also a length‐restricted function, it works differently than strncpy. It appends up to len characters from src to the destination string. But strncat always appends a NUL character to the end of the result, and it does not pad the result with NULs like strncpy. Note that the length of the existing string in the destination array is not accounted for by strncat. It can write up to len characters plus a terminating NUL byte regardless of whether the initial contents of the destination argument leave enough room for them.
尽管strncat 也是一个长度受限的函数,但它和strncpy 存在不同之处。它从src 中最多复制len个字符到目标数组的后面。但是, strncat 总是在结果字符串后面添加一个NUL 字节,而且它不会像strncpy 那样对目标数组用NUL 字节进行填充。注意目标数组中原先的字符串并没有算在strncat 的长度中。stmcat 最多向目标数组复制len 个字符(再加一个结尾的NUL 字节),它才不管目标参数除去原先存在的字符串之后留下的空间够不够。
Finally, strncmp compares up to len characters of two strings. If the strings are unequal before or at the lenʹth character, the comparison stops as it would with strcmp. If the first len characters of the strings are equal, value zero is returned.
最后, strncmp 也用于比较两个字符串,但它最多比较len 个字节。如果两个字符串在第len 个字符之前存在不相等的字符,这个函数就像由cmp 一样停止比较,返回结果。如果两个字符串的前len 个字符相等,函数就返回零。