只是为了解决这个问题,永远不要永远不要使用gets
:它会在你的程序中引入一个故障点。它在 C99 标准中已被弃用,并已从 C2011 标准中删除。这是邪恶的。
说了这么多,让我们来看看代码中的所有问题。
请记住,在 C 中,字符串是由 0 值字节终止的字符序列。这意味着要存储 N 个字符的字符串,您必须留出 N+1char
个存储元素。您的c
数组大小可容纳 1 个元素,这意味着它可以存储的唯一字符串是空字符串。
问题gets
在于它不知道目标缓冲区有多大。当您将数组作为参数传递时,所有被调用函数接收到的都是指向第一个元素的指针。如果您输入 10 个非空白字符,或者 100 或 1000 个,gets
将很乐意将多余的字符存储到数组后面的内存中;这就是您的a
变量被覆盖的原因。这也是为什么gets
最终从语言标准中移除的原因;这种行为促成了许多恶意软件的利用。
您的scanf
调用没有引起问题的原因是您使用了%c
转换说明符,它只从输入流中读取单个字符。如果您使用%s
转换说明符,您会看到与gets
调用相同的结果。
因此,您需要做两件事:首先,您需要声明c
足够大以容纳您期望的最大字符串加上 0 终止符的 1:
#define MAX_SIZE 10 // or however large the string needs to be
...
char c[MAX_SIZE+1];
那么你需要使用fgets
来读取输入:
if ( fgets( c, sizeof c, stdin ) != NULL )
{
// work with c
}