关于getchar()函数的一些看法

一、什么是getchar()
getchar有一个int型的返回值.当程序调用getchar时.程序就等着用户按键.用户输入的字符被存放在键盘缓冲区中.直到用户按回车为止(回车字符也放在缓冲区中).当用户键入回车之后,getchar才开始从stdio流中每次读入一个字符.getchar函数的返回值是用户输入的第一个字符的ASCII码,如出错返回-1,且将用户输入的字符回显到屏幕.如用户在按回车之前输入了不止一个字符,其他字符会保留在键盘缓存区中,等待后续getchar调用读取.也就是说,后续的getchar调用不会等待用户按键,而直接读取缓冲区中的字符,直到缓冲区中的字符读完为后,才等待用户按键(注意:回车键也是一个字符,如果你输入一个字符再按回车,就等于输入缓冲区中有两个字符,getchar()读取第一个字符后还剩回车字符,这个地方需要引起注意。scanf与getchar一样,键入回车后,回车键代表的字符还留在输入缓冲区中,但是gets()函数完成字符输入时,会连回车键一起带走!!!)

二、关于getchar()在按下回车键后是否读取第一个字符

    char a;
    char b;
    cin >> a;
    //cout << line << endl;
    //getchar();
    while ((b = getchar()) != '\n')
        cout << b << endl;
    system("pause");

此处我做了个小实验,然而发现输出的结果是这样的
这里写图片描述
输出是从第二个字符开始输出的,第一个字符直接被吃掉了。此时如果再在while上面加一句getchar(); 结果如下

int line;
    char a;
    char b;
    cin >> a;
    //cout << line << endl;
    getchar();
    while ((b = getchar()) != '\n')
        cout << b << endl;
    system("pause");

这里写图片描述
这里发现字符的输出是直接从第三个字符开始,相比上面的输出又往后移了一个位置。
因此我判断的结论是:getchar()执行一次意味着按顺序向后移动并读取字符,而且应该是先移动再读取字符!!!

这样的话意味着第一个字符永远被吃掉而无法被读出,因此笔者采用下面这个方法

    int line;
    char a;
    char b;
    cin >> line;
    //cout << line << endl;
    //getchar();
    while (line--)
    {   
        cout << "line:" << line << endl;
        while ((b = getchar()) != '\n')
            cout << b << endl;
    }

    system("pause");

这里写图片描述

发现了什么问题??
getchar()要比原来多执行一次才能开始while里面的cout程序,但是字符确实是从第一个字符开始读取的,但是本来应该输出4行的字符只能输出3行。
原因是这样的:
由于cin第一次输入的是int型数据,而getchar()在第一次循环时检测到的刚好是int型后面的’\n’,因此不满足循环的条件而跳过,而第二次循环由于上次吃掉‘\n’而使得getchar()等待用户输入,同时满足while ((b = getchar()) != ‘\n’)而进入循环。
注:当getchar()检测到用户输入的诸如空格符,换行符等时,后面的数据在每次运行getchar()都会被当做字符来使用,即使cin>>lines中lines为int型。
/char型字符占一个字节,而int字符却是两个字节,gerchar()每执行一次是读取一个字符的,因此需要循环两次才能吃掉‘\n’并再次等待用户的输入。/
如何避免这种情况发生,只要在while循环之前再执行一次getchar()就可以了,这样就只需要循环一次便能吃掉‘\n’

int line;
    char a;
    char b;
    cin >> line;
    //cout << line << endl;
    getchar();
    while (line--)
    {   
        cout << "line:" << line << endl;
        while ((b = getchar()) != '\n')
            cout << b << endl;
    }

    system("pause");

这里写图片描述

如果大家有别的看法,欢迎讨论,尤其是关于第一个字符的读取,我目前只能想到这种方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值