获取用户输入的问题(清除stdin)


需求:
        从终端获取用户输入的用户名和密码(有效长度为n),我把 buffer 设为 n+10,这样当用
        户输入过长时可以接收到多余的字符,从而判断出超长了;如果用户直接按回车键,那么应该
        接收到0个字符。

函数:
        fgets( buf, buf_size, stdin)

问题:
        当用户输入超过 buf_size 时,下次再调用 fgets(),它会直接返回而不是等待用户输入,
        因为 fgets() 是直接从 stdin 拿字符的,上次没有取完的字符,直接被 fgets() 拿走然
        后返回;

网上的解决方法:
        1. 使用fflush()。可惜没有任何作用,虽然在Windows下可以,但Linux下没有这个效果。

        2. 调用完 fgets() 后用 while( (ch = getchar() ) != '/n' && ch != EOF );
        清除 stdin 中剩余的字符。问题是如果用户输入小于buf_size, fgets() 成功返回后,
        又进入 getchar() 等待用户输入,用户必须至少多按一次回车键才能得到他想要的结果。

        3. 使用 C++ 的 cin>>buf, 然后再调用 cin.clear() 清除stdin。 这次 stdin 是真的
        可以成功清除了,解决了多余字符问题,但是如果你直接回车,cin>>buf 是不会返回的,
        必须至少输入一个字符后再回车才行,与需求不符。

        4. ......

我的方法:
        1. fgets() 后,直接 stdin->_IO_read_ptr = stdin->_IO_read_end; 即可解决所有
        问题。stdin 实际上是一个结构体指针,如下:
        头文件: /usr/include/stdio.h



        看了glibc的源码后发现 fgets() 只使用 _IO_FILE 中的 _IO_read_end 和 _IO_read_ptr 两个指针而已。
        当然,还需要 #include <libbio.h> 因为 _IO_FILE 在这个头文件中定义的。具体如下:
        头文件: /usr/include/libio.h





        2. 也许还有其它方法......

注意:

        使用fgets(), 如果用户输入小于 buf_size-1(最后一个字符空间留给'/0'),则获取的字符串以'/n'结尾,

        也就是说,fgets()自动把用户输入的回车字符放进去了。

 

===============================================================================

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值