搜索
查看: 907|回复: 13
打印 上一主题 下一主题

关于do while的疑惑

[复制链接]
跳转到指定楼层
楼主
发表于 2014-3-2 09:38:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
5啊哈币
自己写的如下:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char c;
    do
    {
        printf("输入字母\n");
        c=getchar();
        printf("%c\n",c);
  if(c=='y'||c=='Y')
   {
    printf("是\n");
    break;
            }
        else if(c=='n'||c=='N')
   {
    printf("否\n");
    break;
            }
        else
   printf("wrong!\n");
    }
    while(1);
system("pause");
return 0;
}

我想让他提示出入,如果是y就跳出来,是n也会跳出来。
如是不是y和n这两种情况,就重新输入。
但运行结果是
提示输入,我输了下c,然后就提示wrong ,接着又执行了一遍,然后才让我输入,不懂。
以下是运行结果:
-----------/另人糊涂结果/---------------------
输入字母
c                                                 (我就在这输入了一个c,下面就全运行了)
c
wrong!
输入字母                                      (在这一步我什么都没做,直接就往下运行了)

wrong!
输入字母                                     (第二次提示让我输入,)
------------------------------------------------
我不明白我还没有输入为什么就被赋值为空格了,我不明白为什么会跳过第个二输入字母的提示,
求大神解答


最佳答案

查看完整内容

因为你输入的是: c 回车 第一次读取的是c,第二次读取的是回车 读取之后把缓冲区清掉就可以了
沙发
发表于 2014-3-2 09:38:24 | 只看该作者
因为你输入的是: c 回车
第一次读取的是c,第二次读取的是回车

读取之后把缓冲区清掉就可以了
板凳
发表于 2014-3-2 09:41:00 | 只看该作者
沙发。。。。。
地板
发表于 2014-3-2 11:54:08 | 只看该作者
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. int main()
  5. {
  6.     char c[100];
  7.     do
  8.     {
  9.         printf("输入字母\n");
  10.         scanf("%s",c);
  11.         printf("%s\n",c);
  12.         if(!(strcmp(c,"y")||!(strcmp(c,"Y"))))
  13.         {
  14.             printf("是\n");
  15.             break;
  16.         }
  17.         else if(!(strcmp(c,"n")||!(strcmp(c,"N"))))
  18.         {
  19.             printf("否\n");
  20.             break;
  21.         }
  22.         else
  23.             printf("wrong!\n");
  24.     }while(1);
  25.     system("pause");
  26.     return 0;
  27. }
复制代码
5#
 楼主| 发表于 2014-3-2 12:28:15 | 只看该作者
rosynirvana 发表于 2014-3-2 12:20
因为你输入的是: c 回车
第一次读取的是c,第二次读取的是回车

是getchar函数的原因吗?
是不是scanf函数也存在这种情况呢?
我把把刚才那个getchar换成了scanf也存在了
有点乱了被这个搞得.
6#
 楼主| 发表于 2014-3-2 12:30:13 | 只看该作者

用getchar函数不可以吗?为什么改成这种结果?不懂哟
7#
 楼主| 发表于 2014-3-2 12:37:30 | 只看该作者
rosynirvana 发表于 2014-3-2 12:20
因为你输入的是: c 回车
第一次读取的是c,第二次读取的是回车

我用了fflush(stdin)就好了,谢谢您.
8#
发表于 2014-3-2 13:09:07 | 只看该作者
哎呀呀 发表于 2014-3-2 12:37
我用了fflush(stdin)就好了,谢谢您.

有个地方要你注意:
fflush(stdin);是不正规的作法,并不能“正规的”清除缓冲区
建议这样:
  1. while((c=getchar())!='\n'&&c!=EOF)
  2.     ;
复制代码

另外,while的那个分号不是我打错了,自己去GOO.
9#
发表于 2014-3-2 14:59:36 | 只看该作者
哎呀呀 发表于 2014-3-2 12:37
我用了fflush(stdin)就好了,谢谢您.

把代码贴出来,好让新手知道你们在说什么~~
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int main()
  4. {
  5. char c;
  6.     do
  7.     {
  8.         printf("输入字母\n");
  9.         c=getchar();
  10.         printf("%c\n",c);
  11.         if(c=='y'||c=='Y')
  12.         {   
  13.              printf("是\n");
  14.              break;
  15.         }
  16.         else if(c=='n'||c=='N')
  17.         {
  18.                     printf("否\n");
  19.                     break;
  20.             }
  21.             else
  22.             fflush(stdin);    //清空缓存区
  23.                    printf("wrong!\n");
  24.     }while(1);
  25.         system("pause");
  26.         return 0;
  27. }
复制代码
10#
发表于 2014-3-2 16:47:44 | 只看该作者
哎呀呀 发表于 2014-3-2 12:28
是getchar函数的原因吗?
是不是scanf函数也存在这种情况呢?
我把把刚才那个getchar换成了scanf也存在了 ...

getchar一次读一个字符
你输入了两个字符
另一个留在缓冲区内
下一次读取的就是上次输入的回车

fflush(stdin); 只在微软提供的C函数库上有效
这里你不要求严格的除错,那么多写一个getchar就行
  1. printf("输入字母\n");
  2. c=getchar();
  3. getchar();   
  4. printf("%c\n",c);
复制代码


然后就会从缓冲区再读取一个字符,丢弃掉
如果输入没有错误(例如输入一连串的空格再回车的),丢弃掉的就是多余的那个回车
11#
发表于 2014-3-2 16:55:57 | 只看该作者
哎呀呀 发表于 2014-3-2 12:28
是getchar函数的原因吗?
是不是scanf函数也存在这种情况呢?
我把把刚才那个getchar换成了scanf也存在了 ...

scanf非常复杂而且容易出错,近些年的教科书为了省事都直接教用scanf的
其实C最权威的教科书上是在书第七章(一共8章)才提到scanf

这里用scanf大概有两种写法,一种是,大概也就是你出问题的那种
  1. char ch;
  2. scanf("%c", &ch);
复制代码

这里用的占位符是%c,读取一个字符,和getchar一样,会读取缓冲区残留的那个回车

另外一种
  1. char ch[5];
  2. scanf("%4s", ch);
复制代码

这里的占位符是%4s,也就是长度不超过4的字符串。
注意%s占位符会忽略开头的空白字符(空格,回车以及tab制表符),读取到空白字符的时候会结束读取
所以在一个循环连续读取的时候,回车这个占位符就会被忽略,就不再存在这个问题
然后要用字符的时候
  1. if(ch[0] == 'Y')
复制代码
之类的就可以了
12#
发表于 2014-3-2 17:03:12 | 只看该作者
哎呀呀 发表于 2014-3-2 12:30
用getchar函数不可以吗?为什么改成这种结果?不懂哟

最后再说一下缓冲区这个名词

用C标准库函数读取键盘输入(getch之类不是标准库函数),是先把输入的内容送入一个缓冲区内,然后当你确认输入(按了回车键)或者缓冲区满了,才会把输入的内容送给程序处理

仔细考虑一下你输入的过程

第一个字符是c,缓冲区没有刷新,程序认为缓冲区是空的,会等待输入
第二个字符是\n(回车),缓冲区刷新,程序发现缓冲区有东西了,开始处理
程序进行处理,看到了一个getchar(),那么从缓冲区读取一个字符

这时候缓冲区有一个字符\n

第二轮循环,程序发现缓冲区有东西,一个\n,然后getchar()读取,进行处理
就是你看到的结果
13#
 楼主| 发表于 2014-3-7 10:39:36 | 只看该作者
rosynirvana 发表于 2014-3-2 17:03
最后再说一下缓冲区这个名词

用C标准库函数读取键盘输入(getch之类不是标准库函数),是先把输入的内 ...

非常感恩您细致的讲解,真心感谢。
14#
 楼主| 发表于 2014-3-7 10:40:29 | 只看该作者
4399APPLE 发表于 2014-3-2 13:09
有个地方要你注意:
fflush(stdin);是不正规的作法,并不能“正规的”清除缓冲区
建议这样:

好的,明白了,非常感谢您。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

广播台
特别关注
快速回复 返回顶部 返回列表