I've decided to take some of the many suggestions for improvement on my previous question, Easier user input in C++, and actually get it to work as expected. This time around, a few things are different, namely:
- The function will now accept string input with spaces, like
"Ethan Bierlein"
, and not just spit back the first "word" in the input. - The function now also accepts a different input stream rather than just
std::cin
, if, for some reason you do something like that. - The function now allows for a "no-prompt" option, as well, which just means that the argument
prompt
has a default value of""
. - There is an optional way to specify the type of the prompt as well now. It's default type is
std::string
. - The function, now named
get_input
, has it's own namespace,easy_input
, rather than being patched intostd
.
I do have a few concerns about my code though, and I'd like to hear your opinions on them:
- Is it a good idea to declare a static variable, just so I can have a default value for
prompt
? Is it a good idea to have a default value for prompt? - How necessary is it to provide an option to get input from a different input stream?
- Am I writing good C++, or am I doing certain things horribly wrong?
- Is there anything else that stands out for improvment?
easy_input.h
#if HAVE_PRAGMA_ONCE
#pragma once
#endif
#ifndef EASY_INPUT_H_
#define EASY_INPUT_H_
#include <iostream>
#include <string>
#include <boost/lexical_cast.hpp>
namespace easy_input
{
const std::string input_error_message = "an I/O error was encountered.";
static std::string default_prompt = "";
template <typename TInput, typename TPrompt = std::string>
TInput get_input(
const TPrompt& prompt = default_prompt,
std::istream& input_stream = std::cin
);
}
/**
* This function serves as a useful wrapper for getting user input.
* Rather than forcing the user to type out multiple lines every
* time they want to get input, they only have to type one line.
* @tparam TInput - The type of the input to obtain.
* @tparam TPrompt - The type of the prompt to be used. The default type is std::string.
* @param {TPrompt} prompt - The prompt to be used.
*/
template <typename TInput, typename TPrompt = std::string>
TInput easy_input::get_input(
const TPrompt& prompt = easy_input::default_prompt,
std::istream& input_stream = std::cin)
{
std::cout << prompt;
std::string user_input_value { };
if(!std::getline(input_stream, user_input_value)) {
throw std::istream::failure { easy_input::input_error_message };
}
return boost::lexical_cast<TInput>(user_input_value);
}
#endif
main.cpp (tests)
#include <iostream> #include "easy_input.h" int main() { std::string a = easy_input::get_input<std::string>("Enter your name please! "); std::cout << a << "\n"; int b = easy_input::get_input<int>("Enter an integer please! "); int c = easy_input::get_input<int>("Enter an integer please! "); std::cout << b + c << "\n"; std::string d = easy_input::get_input<std::string>(); std::cout << d << "\n"; int e = easy_input::get_input<int>(); int f = easy_input::get_input<int>(); std::cout << e + f << "\n"; }