首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

烦人的gets()函数解决思路

2012-03-19 
烦人的gets()函数我在编写程序需要用到类似代码清单的程序片段:代码清单7-19-2:#include stdio.hvoidmai

烦人的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();
}

热点排行