Code:
//
// basic_input.h
//
// Contains the declaration/definition of console input helper functions
// that make basic console input easier for new C++ programmers.
//
// basic_input:
// template<typename charT, typename traits, typename T>
// inline bool basic_input(std::basic_istream<charT,traits>& is, T& x, charT delim)
// template<typename charT, typename traits, typename Allocator>
// inline bool basic_input(std::basic_istream<charT,traits>& is, std::basic_string<charT,traits,Allocator>& x, charT delim)
// template<typename charT, typename traits>
// inline bool basic_input(std::basic_istream<charT,traits>& is, charT* x, std::streamsize count, charT delim)
// template<typename charT, typename traits, typename T>
// inline bool basic_input(std::basic_istream<charT,traits>& is, T& x)
//
// Returns:
// bool - true if the input succeeded, false otherwise.
//
// Effects:
// This function attempts to read from the input stream into the passed in
// variable up to the specified delimiter. If the data in the stream does
// not match the expected format of the variable type, or if the character
// following the data read in is not the delimiter, then the input fails.
//
// On success, the variable x contains the inputted value. On failure, the
// variable x is cleared (i.e. default-initialized).
//
// On success or failure, the input stream is left in a good state and all
// characters up to and including the delimiter are removed from the stream.
//
// The delimiter defaults to '\n' if not specified.
//
// If the variable type is char* (or some other character pointer), and the
// delimiter has not yet been reached prior to count characters being read
// in, then the input has failed and the array pointed to by the char* will
// be filled with count characters set to null.
//
// Sample usage:
// int i;
// std::cout << "Enter an int: ";
// while (!bip::basic_input(std::cin, i))
// std::cout << "Invalid int! Try again: ";
//
//
// ignore_line:
// template<typename charT, typename traits>
// inline std::basic_istream<charT,traits>& ignore_line(std::basic_istream<charT,traits>& is, charT delim)
// template<typename charT, typename traits>
// inline std::basic_istream<charT,traits>& ignore_line(std::basic_istream<charT,traits>& is)
//
// Returns:
// std::basic_istream<charT,traits>& - the stream passed in.
//
// Effects:
// This function reads and discards all characters in the passed in input
// stream up to and including the first instance of the delimiter. The
// delimiter defaults to '\n' if not specified.
//
// Sample usage:
// std::cout << "Press Enter to Close.\n";
// bip::ignore_line(std::cin);
//
#ifndef BASIC_INPUT_H_
#define BASIC_INPUT_H_
#include <istream>
#include <ios>
#include <string>
#include <limits>
namespace bip
{
template<typename charT, typename traits>
inline std::basic_istream<charT,traits>& ignore_line(std::basic_istream<charT,traits>& is, charT delim)
{
return is.ignore(std::numeric_limits<std::streamsize>::max(), delim);
}
template<typename charT, typename traits>
inline std::basic_istream<charT,traits>& ignore_line(std::basic_istream<charT,traits>& is)
{
return ignore_line(is, is.widen('\n'));
}
template<typename charT, typename traits, typename T>
inline bool basic_input(std::basic_istream<charT,traits>& is, T& x, charT delim)
{
std::ios::fmtflags old_flags = is.flags();
if ((is >> std::noskipws >> x) && (is.eof() || is.get() == delim))
{
is.flags(old_flags);
return true;
}
is.flags(old_flags);
x = T();
is.clear();
ignore_line(is, delim);
return false;
}
template<typename charT, typename traits, typename Allocator>
inline bool basic_input(std::basic_istream<charT,traits>& is, std::basic_string<charT,traits,Allocator>& x, charT delim)
{
if (std::getline(is, x, delim))
return true;
x.clear();
is.clear();
return false;
}
template<typename charT, typename traits>
inline bool basic_input(std::basic_istream<charT,traits>& is, charT* x, std::streamsize count, charT delim)
{
if (is.getline(x, count, delim))
return true;
if (is.gcount()+1 < count)
memset(x, charT(), count);
is.clear();
ignore_line(is, delim);
return false;
}
template<typename charT, typename traits, typename T>
inline bool basic_input(std::basic_istream<charT,traits>& is, T& x)
{
return basic_input(is, x, is.widen('\n'));
}
}
#endif // BASIC_INPUT_H_
Here is sample usage: