以前,scanf 和 %s 用于从键盘输入字符串。 其实还有一种更简单的方法,那就是使用 gets() 函数。 该函数的原型为:
#
char *gets(char *str);
这个函数非常简单,只有一个参数。 参数类型为char*,即str可以是字符指针变量名或字符数组名。
虽然在大多数场景下,我们可以将字符数组的数组名视为指向数组中第一个字符的指针,但C语言中的指针和数组名并不完全等价,不能混淆。 感兴趣的读者伙伴,请点击此处了解详情。
gets()函数的作用是从输入缓冲区中读取一个字符串,并将其存储到字符指针变量str指向的内存空间中。 ()又称为高速缓存(Cache),是内存空间的一部分。 有时,从键盘输入的内容,或者要输出到显示器的内容,会暂时进入缓冲区。 时机成熟时,缓冲区中的所有内容都会被“转储出来”,然后我们就可以看到变量的值被改变了。 刷新,或者屏幕发生变化。
为什么C语言要引入缓冲区? 除了 gets() 之外,还有哪些其他输入/输出函数具有缓冲区? 有没有没有缓冲区的输入/输出函数? 有兴趣的读者请点击此处获取答案。
我们把之前使用scanf输入字符串的程序改一下:
# includeint main(void) { char str[20] = "\0"; //字符数组初始化\0 printf("请输入字符串:"); gets(str); printf("%s\n", str); return 0; }
输出是:
请输入字符串:我爱你
我爱你
可见,gets()函数不仅比scanf更加简洁,而且即使输入字符串中有空格也可以直接输入,而不必像scanf一样定义多个字符数组。 也就是说:
gets(str);
可以完全替代:
scanf("%s", string);
不仅代码更加简洁,而且可以直接输入带空格的字符串。 同样,在上一章中,也可以使用gets()来初始化字符指针变量指向的内存单元。 我们还可以更改该程序并将 scanf 替换为 gets():
# includeint main(void) { char str[30]; char *string = str; //一定要先将指针变量初始化 printf("请输入字符串:"); gets(string); //也可以写成gets(str); printf("%s\n", string); //输出参数是已经定义好的“指针变量名” return 0; }
输出是:
请输入字符串:嗨,我...喜欢你
嗨我...喜欢你
另外,使用gets()函数时请注意:当使用gets()时,系统会从缓冲区中取出最后一个“键入”的换行符然后将其丢弃,因此缓冲区中不会留下换行符。 这意味着如果你之前使用过gets(),然后从键盘给一个字符变量赋值,就不需要吸收回车来清空缓冲区,因为缓冲区中的回车已经被取出来了被 gets() 丢弃。 编写如下程序进行验证:
# includeint main(void) { char str[30]; char ch; printf("请输入字符串:"); gets(str); printf("%s\n", str); scanf("%c", &ch); printf("ch = %c\n", ch); return 0; }
输出是:
请输入字符串:我爱你
我爱你
通道=Y
我们看到在不清除缓冲区的情况下仍然可以输入'Y',因为gets()已经取出了缓冲区中的回车符并将其丢弃。 如果使用scanf而不是gets(),那么在通过键盘给ch赋值之前必须使用()清除缓冲区。