烦人的gets()函数
我在编写程序需要用到类似代码清单的程序片段:
代码清单7-19-2:
#include <stdio.h>
void main()
{
char filename[18];
printf( "Please input the file name again!\n ");
gets(filename);
while(sizeof(filename)> 18)
{
printf( "Error! The file name is too long!\n ");
printf( "Please input the file name again!\n ");
gets(filename);
}
getch();
}
这段代码原本是用于输入检查(即检查用户的非法输入),当用户输入文件名(filename)过长时就要求重新输入,但是。。。。。。
当我们输入过长,原本要进入循环时,却立即跳出循环,同样的问题也出现在getchar()及scanf(),即getchar()编写循环也是不可能进行的。但。。。。。
这是为什么?
请注意清单7-19-2是连scanf()函数的无法正常运行;
另外代码清单7-19-3是可以把scanf()函数用上!
scanf( "%s ",array);/**/
do
{
flag=1;
n=strlen(array);
for(i=0;i <n;i++)
{
if(array[i] < '0 '&&array[i]!= '. '||array[i]> '9 ')
{flag=0;break;}
else if(array[i]== '. '&&flag!=-1)
if(i <=5)
{flag=-1;k=i;}
else {flag=0;break;}
else if(array[i]== '. '&&flag==-1)
{flag=0;break;}
else if(array[i]> '0 '&&array[i] < '9 '&&i==n-1&&flag!=0&&flag!=-1)
{flag=-1;k=i+1;}
}
if(i==n&&flag)
{
j=1;
for(i=k-1;i> =0;i--)
{
s+=(array[i]-48)*j;
j*=10;
}
j=0.1;
for(i=k+1;i <n;i++)
{
s+=(array[i]-48)*j;
j/=10;
}
printf( "the number you have input is %.2f\n ",s);
}
else if(!flag)
{
printf( "Error!\n ");
printf( "Please input the numbers again with the rules!\n ");
scanf( "%s ",array);/**/
}
}while(!flag);
我们在使用scanf(),清单7-19-3可以正常使用,但。。。。改用gets()函数就又不能正常进行!
(另外简单说明一下清单7-19-3:控制用户在输入浮点数时,不能出现非法字符,两个小数点,及小数点前不能超过5位,前半段是把浮点数当字符串输入从而检查,而后者把字符串变回浮点数返回去。如果你对我的编程风格有什么意见照样感谢你反馈。)
问题:gets()函数如何在循环里正确使用;gets()与scanf()在上面的清单里为什么在同样的代码里会有不同的结果?
[解决办法]
while(sizeof(filename)> 18)
你这样判断当然不行啦,sizeof是测试元素空间大小的,你的sizeof(filename)永远都等于18.应该用strlen
来判断输入的字符数.
[解决办法]
gets 和 scanf( "%s ",array); 的区别莫过于 gets 允许接收空格,仅以回车结束输入
而scanf 不接收空白字符,空格、\t、回车都会截断输入
[解决办法]
char filename[18];
..
gets(filename);
while(strlen(filename)> =18) //如果输入超过18个字符就可能出错了
应当定义足够的空间:
#define LEN 128 //举个例子
char filename[LEN];
...
------解决方案--------------------
楼主,我觉得7-19-3 的gets并不错。 如果下面这个程序能运行,是不是也可以说明问题。
#include <stdio.h>
#include <conio.h>
#include <string.h>
void main()
{
char filename[18];
int flag = 0;
printf( "Please input the file name again!\n ");
gets(filename);
do
{
if (strlen(filenameg) > = 6)
{
flag = 1;
}
printf( "Please input the file name again!\n ");
gets(filename);
}
while(!flag);
getch();
}
[解决办法]
cceczjxy() 地解释很不错说~
不过scanf() 和 gets() 真得很麻烦
总是要考虑回车考虑什么的
而且不同的编译器对两个语句的处理也完全不一样
有时候自动换行了 有时候又不换了。。
有时候空格就把字符串结束了 有时候空格又算在字符串了
不过vc6.0 tc2.0 tc3.0编译的时候
char ch[20];
scanf ( "%s ", ch );
这样是绝对不会接受空格到字符串里面的。。。
[解决办法]
1)
首先
char filename[18];
.......
.......
while(sizeof(filename)> 18)
这个循环永远不会被执行
因为 sizeof(filename) 等于 18 无乱你输入什么
sizeof 是在编译时决定的,它返回你定义数据类型的大小,更数据的具体内容无关
你可以用 strlen(filename); 返回字符串的长度,但
程序不应该这样写,因为数据长度超过18就有溢出了
建议把char filename[18];
改成一个足够大的数组
char filename[128];
然后再
while(strlen(filename)> 18)
2)
19.3
是可以用gets的
在gets以你按换行为结束
scanf 以空白符为结束 ,空白符如 空格 tab 换行
我把你的代码改成gets,没任何问题
运行结果:
12345.1234
the number you have input is 12345.12
请按任意键继续. . .
3)
你的代码风格尽快改
象这一陀
for(i=0;i <n;i++)
{
if(array[i] < '0 '&&array[i]!= '. '||array[i]> '9 ')
{flag=0;break;}
else if(array[i]== '. '&&flag!=-1)
if(i <=5)
{flag=-1;k=i;}
else {flag=0;break;}
else if(array[i]== '. '&&flag==-1)
{flag=0;break;}
else if(array[i]> '0 '&&array[i] < '9 '&&i==n-1&&flag!=0&&flag!=-1)
{flag=-1;k=i+1;}
}
挤在一行,怎么调试啊。。。。
[解决办法]
当我连续输入12345678或输入连续ABCDEFG时,按照你的代码应是不停执行循环,直到输入的字符少于6个为止。可是在我的WIN-TC或TC2.0下都是循环无法正确执行两次。(因为你的代码至少会执行一次循环)。
---------------------------------------------------
#include <stdio.h>
#include <conio.h>
#include <string.h>
void main()
{
char filename[18];
int flag = 0;
printf( "Please input the file name\n ");
gets(filename);
if (strlen(filename) > = 6)
{
flag = 1;
}
while (!flag)
{
printf( "Please input the file name again!\n ");
gets(filename);
if (strlen(filename) > = 6)
{
flag = 1;
}
}
getch();
}