zoukankan      html  css  js  c++  java
  • while ((ch = getchar()) != EOF)中ch定义为char还是int型?cin、scanf等如何结束键盘输入

    2013-07-09 18:55:42

    EOF是文件的结束符,具体可以作为文本文件的结束符,也可以作为键盘输入char类型数据时的结束符。对于不同的系统,EOF的定义可能不同,一般定义为-1。因为char类型的数据范围是0~255,不可能是-1,EOF定义为0~255之外的数据理论上都是可以的。

    一般在C语言中用getchar()函数或scanf获取char类型时,可用EOF作为结束符。但对于C++,若用getchar()函数或scanf获取char类型时,也可用EOF作为结束符,这是兼容C的特性;但若用cin获取char类型数据,若试图用EOF结束输入,输入ctrl+z时则会陷入死循环,具体见下面的实例。

    小结:

    1. C语言中用getchar()函数或scanf获取char类型时,可用EOF作为结束符,见测试1
    2. 对scanf,要在输入ctrl+z时,结束循环,用while ( scanf("%c",&ivar) != EOF ),见测试5;测试4、6是错误的用法;
    3. EOF就是一宏定义,用cin获取输入时,输入ctrl+Z不可结束循环,只是结束了流的输入,因此陷入死循环,见测试3
    4. 注意EOF的使用场合,EOF本质就是一个宏定义,一般为-1,弄清楚这个就不会在用scanf以及cin输入时用EOF去作为结束条件了;
    5. 对于cin常用的是用while(cin>>ch)结束,这是与cin的工作方式有关的,这里不再赘述,不要将cin与EOF结合起来使用,如测试3所示,就是一种很另类的写法。

    下面给出了C语言下EOF的测试、以及C++下用getchar()函数获取输入以及用cin获取输入时的测试。


    测试1:

    C语言下EOF的测试代码:

     1 #include <stdio.h>
     2 
     3 int main()
     4 {
     5     //int ch;
     6     
     7     char ch;
     8 
     9     while ( ( ch = getchar() ) != EOF )
    10     {
    11         putchar(ch);
    12     }
    13 }

    输入ctrl+z可结束循环。若定义ch为int型,同样可以正常结束循环,在好多文章(如博文http://www.cnblogs.com/youngforever/articles/3180812.html,以及http://www.cnblogs.com/youngforever/articles/3180896.html

    提到不能将ch定义为char,不是为何???

    原因分析见http://www.cnblogs.com/youngforever/p/3199564.html


    测试2:

    C++下用getchar()函数获取输入的测试

    上面的是对C语言而言的,一般在C语言中用getchar()函数或scanf获取char类型时,可用EOF作为结束符。但对于C++,若用getchar()函数或scanf获取char类型时,也可用EOF作为结束符,这是兼容C的特性;如下:

     1 #include <iostream>
     2 using namespace std;
     3 
     4 int main()
     5 {
     6                //int ch;
     7     char ch;
     8 
     9     while ( ( ch = getchar() ) != EOF )
    10     {
    11         putchar(ch);
    12     }
    13 }

    与上面的C代码运行结果一样,输入ctrl+z可结束循环。若定义ch为int型,同样可以正常结束循环。


    测试3:

    C++下用cin函数获取输入的测试

    但若用cin获取输入,就不能用EOF作为结束符。我们知道用cin时,一般这样写while(cin>>ch),windows下,输入ctrl+z,便可结束输入(具体原因,参见cin的介绍)。

     而下面的写法就是很另类的写法,会使得程序陷入死循环:

     1 #include <iostream>
     2 using namespace std;
     3 
     4 int main()
     5 {
     6     char ivar;
     7     //int ivar;
     8     cin>>ivar;
     9     while ( ivar != EOF )
    10     {
    11         cout<<"display the input : "<<ivar<<endl;
    12 cin>>ivar; 13 } 14 }

    ivar为char类型时,会显示从键盘上输入的一切字符,除非ivar的值为-1,但因为ivar是char类型的,因此通过cin输入的ivar不可能为-1,自由通过ctrl+c才能结束程序,若试图通过输入ctrl+z,则会一直输出最后输入的字符,如下为上面代码的运行结果:

    (可以看到,输入-1,会当做字符'-'  '1'处理,而输入ctrl+z后,则一直输出最后输入的字符d,按下ctrl+c才结束)

    13
    display the input : 1
    display the input : 3
    -1
    display the input : -
    display the input : 1
    fsi
    display the input : f
    display the input : s
    display the input : i
      2  d
    display the input : 2
    display the input : d
    ^Z
    display the input : d
    display the input : d
    display the input : d
    display the input : d
    display the input : d
    display the input : d
    display the input : d
    display the input : d
    display the input : d
    display the input : d
    display the input : d
    display the input : d
    display the input : d
    display the input : d
    display the input : d
    display the input : d
    display the input : d
    display the input : d
    display the input ^C请按任意键继续. . .

    原因分析:

    cin将ctrl+z作为输入流的结束,此时再从键盘接收输入,而ivar的值保留为上一个从cin接收的值d,ivar='d',这样while 的条件( ivar != EOF )一直为true,因此陷入死循环

     一直执行while中的cout,cin不再执行,因为输入的ctrl+z已经结束了流的输入。

     若上面代码中的ivar为int型,输入-1便可结束循环,因为EOF就是-1,但若输入ctrl+z,陷入死循环,原因同上。

    ivar为int型时的运行结果:

    (输入-1结束循环)

    2
    display the input : 2
    89
    display the input : 89
    -23
    display the input : -23
    -1
    请按任意键继续. . .

    (输入ctrl+z陷入死循环,要用ctrl+c结束):

    12
    display the input : 12
    -23
    display the input : -23
    ^Z
    display the input : -23
    display the input : -23
    display the input : -23
    display the input : -23
    display the input : -23
    display the input : -23
    display the input : -23
    display the input : -23
    display the input : -23
    display the input : -23
    ^C请按任意键继续. . .

    测试4:

    scanf函数输入int(输入ctrl+z,不会陷入死循环):

     1 #include <iostream>
     2 using namespace std;
     3 
     4 int main()
     5 {
     6                 int ivar;
     7     scanf("%d",&ivar);
     8     while ( ivar != EOF )
     9     {
    10         printf("display the input : 
    ");
    11         printf("%d
    ",ivar);
    12         scanf("%d",&ivar);
    13     }
    14 
    15     return 0;
    16 }

    此时,输入-1便可结束循环,但是输入ctrl+z不会陷入死循环,而是输出上一个scanf输入的数据,这是因为循环的结束条件是输入-1,ctrl+z不是-1,因此不会结束循环,但是scanf函数也不会结束,因为对于scanf函数而言,ctrl+z并不是它的结束标志,因此会输出ivar,而ivar保持原来的值。

    运行结果为:

    89
    display the input :
    89
    -23
    display the input :
    -23
    ^Z
    display the input :
    -23
    ^Z
    display the input :
    -23
    -1
    请按任意键继续. . .

    测试5:

    scanf函数控制输入的正确用法:

    #include <iostream>
    using namespace std;
    
    int main()
    {
        char ivar;
        while ( scanf("%c",&ivar) != EOF )
        {
            printf("display the input : 
    ");
            printf("%c
    ",ivar);
        }
    
        return 0;
    }

    运行结果与测试1相同。 


    测试6:

    scanf函数控制输入的错误用法:

    scanf函数输入char(输入ctrl+z,不会陷入死循环):

    #include <iostream>
    using namespace std;
    
    int main()
    {
        char ivar;
        scanf("%c",&ivar);
        while ( ivar != EOF )
        {
            printf("display the input : 
    ");
            printf("%c
    ",ivar);
            scanf("%c",&ivar);
        }
    
        return 0;
    }

    测试结果:

    (可以看到scanf是可以接受回车的,在输出时同样为回车,且输入-1时,是当做字符处理的,因为ivar此时为char类型,输入ctrl+z时不结束循环,输出为为右箭头,原因未知)

    12a
    display the input :
    1
    display the input :
    2
    display the input :
    a
    display the input :
    
    
    -1
    display the input :
    -
    display the input :
    1
    display the input :
    
    
    2s^Z
    display the input :
    2
    display the input :
    s
    display the input :
    
    ^Z
    display the input :
    
    2
    display the input :
    2
    display the input :
    
    
    display the input :
    
    
    ^C请按任意键继续. . .
  • 相关阅读:
    谈谈Ext JS的组件——组件基类:Ext.Component
    谈谈Ext JS组件之引子
    安装Compass时不能访问服务器的问题
    Android监听电池状态
    为macbook双系统的windows装驱动
    Activity中的四种启动模式
    【翻译】Ext JS 6 Beta发布
    eclipse下出现奇怪字符的解决方法
    浅谈设计模式
    【翻译】Ext JS 5:为不同设备设置不同的主题
  • 原文地址:https://www.cnblogs.com/youngforever/p/3180901.html
Copyright © 2011-2022 走看看