概述
在学习 C/C++
的一开始,我们就接触到基本的输入输出,例如printf/scanf
或者cout/cin
,
但是在涉及用户输入时总是存在可靠性问题:我们无法确保用户输入的信息是合法的,比如要求输入一个数字,但是用户提供的是一串字符串等等,或者要求数字满足一定范围等,我们只能每次手动在外层加一个循环和判断条件,非常繁琐。
在本文中实现了一个简单的获取安全输入的封装SafeInput
,使得在编程中尽可能摆脱这类涉及用户输入参数的处理细节。
使用示例
指定获取一个int
类型的值,要求大于 0 且小于
5,如果输入不满足要求,则会提示重新输入
1 2 int s = SafeInput ().get <int >("Please input a int in (0,5): " , [](int p) { return 0 < p && p < 5 ; });
指定获取一个double
类型的值,并且在获取值之后会回显这个值,需要用户继续输入Y
确认,否则提示重新输入
1 double d = SafeInput ().get <double >("Please input a double: " , true );
提示用户输入Y|N|Q
进行确认,输入Y|N
将通过布尔变量返回,输入Q
则会使用exit(0)
直接退出程序
1 bool s = SafeInput ().confirm ("Continue or exit?" );
程序暂停并等待,直到获取到回车后,程序继续执行
使用要求
示例中的 1 和 2
体现了最主要的用法,其中输入的合法性检查和对输入的再次手动确认都是可选的,一共有四种组合,函数原型依次为
1 2 3 4 5 6 7 8 9 10 11 template <typename T, typename CheckerType>T get (const std::string &msg, CheckerType checker,bool confirm) const ;template <typename T>T get (const std::string &msg, bool confirm) const ;template <typename T, typename CheckerType>T get (const std::string &msg, CheckerType checker) const ;template <typename T>T get (const std::string &msg) const ;
示例中的 3 和 4 则是作为常用情景被直接提供
1 2 3 4 5 bool confirm (const std::string &msg) const ;bool confirm () const ;void pause () const ;
注意:
建议使用 lambda
表达式提供合法性检查,要求返回布尔类型的检查结果,指定的输入类型T
则通过函数模板提供。
每一次的输入都处于循环之中,无论输入成功,还是失败再次输入,都会清空缓冲区,因此不支持连续的输入,这是出于可靠性的考虑。
用于判断的特殊字符(Y|N|Q
)均不区分大小写。
默认会将所有的提示语输入到std::cout
,并且从std::cin
获取用户输入,但是也支持在构造函数中指定其它的输入和输出流。
1 2 3 4 5 SafeInput () : m_in (std::cin), m_out (std::cout) {}explicit SafeInput (std::istream &in) : m_in(in), m_out(std::cout) { }SafeInput (std::istream &in, std::ostream &out) : m_in (in), m_out (out) {}
完整的使用示例如下
main.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #include "safe_input.hpp" int main (int argc, char *argv[]) { auto s = SafeInput ().get <int >("Please input a int in (0,5): " , [](int p) { return 0 < p && p < 5 ; }); std::cout << "s=" << s << "\n" ; auto d = SafeInput ().get <double >("Please input a double: " , true ); std::cout << "final: d=" << d << "\n" ; auto p = SafeInput ().get <bool >("input a bool: " , true ); std::cout << "final: p=" << p << "\n" ; SafeInput ().confirm ("Continue or exit?" ); SafeInput ().pause (); return 0 ; }
源代码
源文件放置在Github仓库:Allay 。