像strcat
和strcmp
这样的函数是否需要以空字符结尾的字符串作为参数,或者是否可以接受任何字符数组?
所有文档都表明它必须以空值终止,但其中一个最知名的在线参考文献(http://cplusplus.com)给出了以下作为strcmp
的示例:
/* strcmp example */
#include <stdio.h>
#include <string.h>
int main ()
{
char szKey[] = "apple";
char szInput[80];
do {
printf ("Guess my favourite fruit? ");
gets (szInput);
} while (strcmp (szKey,szInput) != 0);
puts ("Correct answer!");
return 0;
}
答案 0 :(得分:5)
是的,函数需要以null结尾的字符串。但是,您上面列出的示例确实使用以null结尾的字符串。例如,行
char szKey[] = "apple";
描述附加了空终止符的字符串,即使它在源代码中不是立即显而易见的。 C中的任何字符串文字都会自动以空值终止,即使您没有明确地将请求放在自己中(尽管有一个例外,我们将在一分钟内看到)。
此外,在行
gets (szInput);
函数gets
自动将空终止符附加到从控制台读取的字符串的末尾。实际上,除了极少数例外(例如众所周知的复杂strncat
函数),<string.h>
中的所有字符串操作函数都会自动附加一个空终止符。除非你自己明确地弄乱字符字节,否则在常见用法中很少会以非空终止字符串结束。
也就是说,有许多方法可以获取非空终止的字符串。例如,如果您定义这样的字符串:
char hello[5] = {'h', 'e', 'l', 'l', 'o'}; /* Careful! */
此数组不会以空值终止,因为您已明确列出了您希望它拥有的值。这意味着你拥有的是一个字符数组而不是字符串。如果您尝试调用
printf("%s\n", hello);
您将遇到未定义的行为,因为该数组不是以空值终止的。
此外,如果您使用任何原始内存操作例程,如memcpy
或memmove
,那么您需要小心确保复制或显式设置null终止符,因为这些例程具有没有null终止符的概念。
另外,术语的一小部分 - NULL
通常是指一个空指针,即一个明确标记为指向无对象的指针。 null-terminator中的null引用具有数值0的字符,并且是用于指示已到达字符串结尾的字符(不是指针)。虽然名称相同(并且有相似之处),但最好不要混淆两者。
希望这有帮助!
答案 1 :(得分:1)
gets()
执行null-terminate,szKey[] = "apple";
以null结尾。 "apple"
是一个字符串文字,始终以null结尾。
strcmp
要求将字符串复制为具有\0
终止符,否则它可能会在字符串末尾运行并导致访问冲突。
strcat
还要求其参数被\0
终止。
答案 2 :(得分:1)
字符串需要NUL终止,但我没有看到该代码中NUL终止有任何问题。
我应该补充一点,这几乎是它没有的唯一的问题。特别是使用gets
是不可原谅的。
答案 3 :(得分:0)
根据定义,字符串始终以NULL结尾。
"apple"
实际上被编译器视为apple\0
。
答案 4 :(得分:0)
绝对必须以空终止。
像strcmp这样的比较函数必须有一些东西来阻止比较,那就是空字符。
还有其他函数,如strncmp,它采用长度参数。在这种情况下,字符串不必为空终止,因为您提供了要比较的字符数。
答案 5 :(得分:0)
它们必须以NULL结尾,因为长度未知。库函数的工作方式是从字符串的开头开始,遍历每个字符,直到遇到空字节。如果不是这种情况,函数将继续进入不应该存在的内存中。
答案 6 :(得分:0)
是什么让你认为那些/不是/ null终止?字符串文字自动为空终止,并且(假设缓冲区中有足够的空间)gets()也将为null终止。
那一点 - 如果缓冲区中有空格,那么获取只会终止 - 这是你应该使用getsn()而不是gets()的原因。