Aslcwd 发表于 2019-5-28 21:56:16

飞C的单链表视频----死循环,不断循环输入字符,读取字符,读取回车的问题

本帖最后由 Aslcwd 于 2019-5-28 21:59 编辑

#include <stdio.h>

int judge(char ch);
int judge(char ch)
{
        switch(ch)
        {
                case 'y':return 0;
                case 'n':return 1;
                default :return 2;
        }
}

int main(void)
{
        char ch;
        int x,i=0;

        while(1)
        {
                printf("\n是否录入y/n:");
                ch = getchar();
        //        getchar();        // 去掉前面的第一个双斜杠就可以正常运行
               
                x = judge(ch);
               
                printf("x的值是%d,ch的值是%c\n",x,ch);
               
                if (x==1) // 输入的是n,跳出死循环
                {
                        break;
                }
               
                if (x>1)// 输入不是y或n
                {
                        printf("输入的值错误!\n") ;
                        printf("ch的值为%c,不是y或n,而且x的值是%d!\n",ch,x);
                }
               
                if (x<1) // 输入的是y,继续循环
                {
                        i++;
                        printf("目前录入了%d本书!\n\n******************\n",i);
                }
        }
       
        printf("总计录入了%d本书!\n",i);
       
        return 0;
}

Aslcwd 发表于 2019-5-28 22:02:24

我发现读取键盘字符语句
getchar();
如果放在死循环的开头,读取y/n的时候
你输入y后按回车,循环会立刻执行两遍
因为读取了一个y和一个回车
第三次才会让你重新输入,读取键盘

Aslcwd 发表于 2019-5-28 22:04:08

如果你们运行我发的代码,会发现一直出现这种情况
除非把
      //      getchar();      // 去掉前面的第一个双斜杠就可以正常运行
这行代码的第一个双反斜杠去除
这样输入y和回车就不会有问题

Aslcwd 发表于 2019-5-28 22:07:41

带你学C带你飞系列视频中,单链表1视频
里面的函数只有一个getchar();
当我想要优化程序
目标使键盘输入错误不是y/n的时候出现警告提醒
发现每次运行后循环两遍
第三遍才能输入
于是编写了1楼的程序测试
发现回车真是个麻烦

ba21 发表于 2019-5-29 00:07:23

首先
你输入:
fishc回车
那么他有 6个字符 fishc 5个,加1个 回车

看代码

ch = getchar();// 接收1个,还有1个 回车 在键盘缓冲区;剩下的这个你得处理啊,不处理肯定会有问题
getchar();// 这就是处理剩下回车。

假如,你没软事输入很多字符然后回车呢。
ch = getchar();
getchar();
那么这样肯定也不行
那就得这么改

ch = getchar();// 接收第1个
while(getchar()!='\n') continue; // 其余的这么处理掉

Aslcwd 发表于 2019-5-29 11:01:04

本帖最后由 Aslcwd 于 2019-5-29 16:24 编辑

ba21 发表于 2019-5-29 00:07
首先
你输入:
fishc回车

昨天到现在查了很多资料整理了一下方法:

方法1:
两次使用getchar();
第二次就能吃掉回车符
缺点只能应对,一次键加回车
按两次键加回车会出bug

方法2:
使用一次getchar();
scanf("%*c");
类似于吃掉字符,可以忽略换行符
还可以使用类似
scanf("%*[^/n]");
缺点都是
缺点只能应对,一次键加回车
按两次键加回车会出bug

方法3:
getche();
这种获得字符方法不需要使用回车
按啥是啥,立即执行,方便得很
缺点在于输入错误无法删除重新输入

方法4:
getchar();
while(getchar()!='\n')
{
      continue;
}
把不是回车符号的循环掉
不论按多少字符,只获取第一个,其余的全部清除
基本完美收官
适用于各个版本编译器

方法5:
getchar();
fflush(stdin);
清除字符语句
清空所有
完全完美部分编译器并不支持该语句

代码如下:
#include <stdio.h>

int judge(char ch);
int judge(char ch)
{
      switch(ch)
      {
                case 'y':return 0;
                case 'n':return 1;
                default :return 2;
      }
}

int main(void)
{
      char ch;
      int x,i=0;

      while(1)
      {
                printf("\n是否录入y/n:");
               
                ch = getchar();
               
                fflush(stdin);
               
                x = judge(ch);
               
                printf("\n您输入了:%c\n",ch);
               
                if (x==1) // 输入的是n,跳出死循环
                {
                        break;
                }
               
                if (x>1)// 输入不是y或n
                {
                        printf("输入的值错误!\n") ;
                        printf("ch的值为%c,不是y或n,而x的值是%d!",ch,x);
                        printf("\n\n---------------------\n");
                }
               
                if (x<1) // 输入的是y,继续循环
                {
                        i++;
                        printf("目前录入了%d本书!\n\n---------------------\n",i);
                }
      }
      
      printf("总计录入了%d本书!\n",i);
      
      return 0;
}

暗pluto 发表于 2019-5-29 14:33:24

Aslcwd 发表于 2019-5-29 11:01
昨天到现在查了很多资料整理了一下方法:

方法1:


谢谢楼主的分享,之前在做实验的时候也遇到过,也总结过了,不过删掉了
当时用的是getch(),与你上面的getche()差不多

暗pluto 发表于 2019-5-29 14:53:16

暗pluto 发表于 2019-5-29 14:33
谢谢楼主的分享,之前在做实验的时候也遇到过,也总结过了,不过删掉了
当时用的是getch(),与你上面 ...

不过楼主, fflush(stdin)这个并不是所有编译器都适用的,目前看,我的vs2015就没办法用,变成了
rewind(stdin)可用了

Aslcwd 发表于 2019-5-29 16:22:50

暗pluto 发表于 2019-5-29 14:53
不过楼主, fflush(stdin)这个并不是所有编译器都适用的,目前看,我的vs2015就没办法用,变成了
rewind ...

确实会根据编译器有差别
页: [1]
查看完整版本: 飞C的单链表视频----死循环,不断循环输入字符,读取字符,读取回车的问题