C语言gets函数的疑问求解答
{
char st[20],cs[5][20];
int i,j,p;
printf("input country's name:\n");
for(i=0;i<5;i++)
gets(cs[i]);
printf("\n");}
上面这个程序定义的二维字符数组char cs[5][20],gets函数格式是gets(字符数组名),但是在程序中为什么要写成gets(cs[0])这种形式,表达什么意思啊?为什么不写成gets(cs)呢? 展开
gets函数的原型是char*gets(char*buffer);
就是说要求一个实参是指针类型。
然后我们看一下char cs[5][20]表示什么,cs[5][20]是一个二维的字符数组,当然,你可以把他看做是一个一维的指针数组。相当于是char *cs[5],cs[5]中的每个元素都是一个指针,都指向一个长度为20的字符串。
所以cs[0]就是第一个指针,他指向一个字符串。所以可以把cs[0]作为参数传递进去。
那么cs是什么呢?它是二维数组的首地址。在这里确实是和cs[0]是一样的,但是接下来不能满足你程序的要求,也就是指向第二个字符串的开头。
我们这样来想。
cs[5][20]是一个5*20的表格,5行20列
cs[0]:第1行的首地址
cs[1]:第2行的首地址
cs[2]:第3行的首地址
cs[3]:第4行的首地址
cs[4]:第5行的首地址
而cs则永远是这个数组的首地址,相当于指向第一行第一个位置。
那么当你循环的时候,如果是cs[i],gets(cs[i])就是像每一行里面写入字符串,写完一行,换一行在写
,而写成gets(cs)的话,则永远都是从第一行第一个元素开始写入,后面的就会覆盖前面的元素。
你说的gets(字符数组名)这个表达其实是不准确的,所以会误导你,你定要去看函数原型,才知道函数到底是怎么用的。如果说,是一个一维数组st[N]那么,gets(st)是向这个数组输入字符串
(字符数组名就是首地址就是指针)
但是对于二维数组cs[M][N],gets(cs)确实可以,字符数组名就是首地址就是指针,但是从图里可以看到,cs是整个M*N这个表的开头。而不能指向每一行的开头。这样你就不能进行后续的操作了。而cs[i]则是每一行的开头,你可以把它看做是M*N这个表的每一行的数组名。
感谢大神,还有一个问题,你写的最后一句话的意思是不是,如果写成gets(cs),是不是先写入第一行20个字符的字符串,然后再写入第二行20个元素就将第一行的覆盖了,最后输出结果是最后一行的字符串?
是的。gets(cs),我们知道cs是指在最开头的,那么你永远都是在向第一行的二十个格子里面赋值。后面的都没用到。如果你用puts(cs)打印,那么他也是从开头打印,那么是没有问题的,打印你最后赋值的那二十个字符(前面的被覆盖了),而如果你是用
for(i=0;i<5<i++)
puts(cs[i])
来打印的话,第一次循环,puts(cs[0])的时候,是和上面一样,但是后续的就会打印乱码,因为你后面4行的格子其实都是空的,所以会打印一些乱七八糟的东西。
你用下面的代码演示一下就知道了
#include<stdio.h>
main()
{
char st[20],cs[5][20];
int i,j,p;
printf("input country's name:\n");
for(i=0;i<5;i++)
gets(cs);/*循环赋值,但总是从最开头开始,向第一行20个格子赋值*/
printf("\n");
puts(cs);/*打印结果为最后赋值的20个元素*/
printf("\n");
for(i=0;i<5;i++)/*循环逐行打印*/
puts(cs[i]);/*第一行正常,是最后赋值的20个元素,后面全是乱码,因为从未赋值*/
}
gets(cs)也是可以的,但是得不到你想要的结果
你的程序有个致命错误,应该是c的一个bug吧
在gets或者%c %s的输入时,如果前面有输入,需要考虑回车符
因为回车也是字符,并且不会被前面的输入接受,但是回车是当结束输入使用的,有必不可少
所以需要处理一下,不然这种字符的输入会接受上面输入的那个回车符,二接受不到真正的输入
处理方式两个fflush(stdin)清理缓存或者getchar吸收这个回车
那个for循环输入了这5个字符串的值,即gets(cs[0])输入第一个字符串,依次类推