什么类型的字符串是C字符串函数的合法输入?

时间:2011-11-11 03:06:47

标签: c string

strcatstrcmp这样的函数是否需要以空字符结尾的字符串作为参数,或者是否可以接受任何字符数组?

所有文档都表明它必须以空值终止,但其中一个最知名的在线参考文献(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;
}

7 个答案:

答案 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);

您将遇到未定义的行为,因为该数组不是以空值终止的。

此外,如果您使用任何原始内存操作例程,如memcpymemmove,那么您需要小心确保复制或显式设置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()的原因。