如果您键入的字符超过四个,那么多余的字符和空终止符将被写入数组末尾之外,从而覆盖不属于数组的内存。这是缓冲区溢出。
C 不会阻止你破坏你不拥有的内存。这会导致未定义的行为。你的程序可以做任何事情——它可能会崩溃,它可能会默默地丢弃其他变量并导致令人困惑的行为,它可能是无害的,或者其他任何事情。请注意,不能保证您的程序将可靠地工作或可靠地崩溃。你甚至不能指望它立即崩溃。
这是一个很好的例子,说明为什么scanf("%s")
是危险的,永远不应该使用。它不知道数组的大小,这意味着无法安全地使用它。相反,请避免 scanf 并使用更安全的东西,例如fgets():
fgets() 从流中最多读入一个小于 size的字符,并将它们存储到 s 指向的缓冲区中。在 EOF 或换行符后停止读取。如果读取了换行符,则将其存储到缓冲区中。终止的空字节 ('\0') 存储在缓冲区中的最后一个字符之后。
例子:
if (fgets(A, sizeof A, stdin) == NULL) {
/* error reading input */
}
烦人的是, fgets() 将在数组末尾留下一个尾随换行符 ('\n')。因此,您可能还希望代码将其删除。
size_t length = strlen(A);
if (A[length - 1] == '\n') {
A[length - 1] = '\0';
}
啊。一个简单的(但破碎的)scanf("%s")
变成了一个 7 行的怪物。这是今天的第二课:C 不擅长 I/O 和字符串处理。可以做,也可以安全做,但是C会一直踢和尖叫。