When you're learning C++, even very simple programs can feel more complicated than expected.
This is especially noticeable if you're coming from Python.
In Python, input is simple:
name = input("Enter your name: ")
print("Hello", name)
Then you move to C++ and suddenly you need to understand things like:
std::cin >> value;
and:
std::getline(std::cin, value);
You also need to know why they behave differently, what happens with spaces, and why mixing them can sometimes cause problems.
None of this is necessarily bad. C++ gives you much more control.
But when you're just starting out, sometimes you simply want to get a value from the user and continue learning.
That's why I made EasyIn.
The idea
EasyIn is a small header-only library that gives beginners a simpler way to handle common input.
Instead of writing:
std::cin >> age;
you can write:
input(age);
And instead of:
std::getline(std::cin >> std::ws, name);
you can write:
inputln(name);
The goal is not to replace C++ streams.
The goal is to make the first steps into C++ a little easier.
A simple example
With EasyIn:
#include <print>
#include <string>
#include "easyin.hpp"
using namespace easyin;
int main() {
std::string name;
int age{};
std::print("Enter your name: ");
inputln(name);
std::print("Enter your age: ");
input(age);
std::println("Hello {}, you are {} years old.", name, age);
}
The code is still C++, but the input side becomes a little easier to read.
You have:
input()
inputln()
and with modern C++:
print()
println()
That makes simple programs feel a bit more consistent.
input() vs inputln()
EasyIn has two main input functions.
input() reads a single value:
int age;
input(age);
It also works with other types:
double price;
input(price);
std::string word;
input(word);
When used with a string, it reads one word.
So if the user enters:
Hello world
input() reads:
Hello
For lines of text, you can use inputln():
std::string name;
inputln(name);
If the user enters:
John Smith
the whole name is stored.
inputln() also skips leading whitespace.
For example, input like:
John Smith
is read as:
John Smith
It also skips blank lines before the next piece of text.
This is intentional.
For normal console programs, it avoids some of the common whitespace problems that appear when mixing formatted input with line-based input.
It can also be useful when reading simple files where indentation, blank lines, or extra whitespace at the beginning of a line are not important.
For example, a loosely formatted file such as:
Apple
Banana
Orange
can still be read as:
Apple
Banana
Orange
when each value is read using inputln().
This does not make inputln() a general whitespace cleaner. Spaces inside the line and trailing whitespace are still part of the string.
If exact formatting matters — for example, if leading spaces or blank lines need to be preserved — you can always use std::getline() directly.
EasyIn is meant for the common case, while the normal C++ stream tools are still available when you need more control.
So beginners get a simple distinction:
input() // one value
inputln() // one line of text
Invalid input
Another thing that can confuse beginners is what happens when someone enters the wrong type of value.
For example:
int age;
but the user enters:
hello
EasyIn returns a bool, so you can check whether the input succeeded:
int age{};
if (!input(age)) {
std::println("Invalid input.");
}
When a read fails, EasyIn also attempts to clean up the stream.
It clears the failed state and discards the rest of that input line so another read can be attempted.
That keeps basic error handling short without requiring beginners to immediately deal with clear() and ignore() themselves.
Retrying invalid input safely
Because input() returns false when a read fails, we can use it to ask the user to try again:
int age{};
while (!input(age)) {
std::println("Please enter a valid number.");
}
This works for ordinary invalid input.
For example, if the user enters:
hello
instead of a number, EasyIn attempts to clean up the failed input so another read can be attempted.
There is one important case to consider, though: the input stream may have ended.
This can happen when reaching the end of a file, when standard input is closed, or when another stream error prevents further reading.
In that situation, repeatedly calling input() would never produce a new value.
EasyIn provides:
inputAvailable()
which lets us check whether the stream is still in a good state before trying again.
For example:
#include <print>
#include "easyin.hpp"
using easyin::input;
using easyin::inputAvailable;
int main() {
int age{};
while (!input(age)) {
if (!inputAvailable()) {
std::println("No more input available.");
return 1;
}
std::println("Please enter a valid number.");
}
std::println("You entered: {}", age);
}
The flow is:
input() -> try to read a value
inputAvailable() -> check whether another attempt makes sense
inputAvailable() does not check whether the user has already typed something or whether characters are currently waiting to be read.
Internally, it simply checks the current state of the stream:
return in.good();
This makes it useful after a failed input() or inputln() call.
If the failure was caused by ordinary invalid input and EasyIn successfully cleaned up the stream, inputAvailable() will normally return true.
If the stream has reached the end of its input or is otherwise no longer in a good state, it returns false.
Like the other EasyIn functions, it can also work with another input stream:
inputAvailable(file);
So the three main operations are:
input() // read one value
inputln() // read one line of text
inputAvailable() // check whether the stream is still usable
The goal stays the same: keep common input code short and beginner-friendly while still using the normal C++ stream system underneath.
It still uses C++ streams
EasyIn isn't trying to hide C++ completely.
Underneath, it still uses normal C++ input streams.
That means you can also use it with files or other streams:
#include <fstream>
std::ifstream file("data.txt");
int number;
input(number, file);
Or:
std::string line;
inputln(line, file);
std::cin is simply the default.
The whitespace behavior of inputln() can also be useful here.
If a file contains unnecessary indentation or blank lines, and that formatting is not meaningful to your program, inputln() can skip over it automatically.
If you need to preserve the file exactly as written, you can use std::getline() instead.
The underlying stream system is still there whenever you need it.
Why I made it
The main reason I made EasyIn was because I remembered how different C++ felt compared to languages like Python.
Something as basic as getting input suddenly required learning several different concepts at once.
And while understanding std::cin, std::getline(), stream states, whitespace, and error handling is important, I don't think beginners necessarily need to deal with all of that in their first programs.
Sometimes you just want to write:
input(age);
and move on to learning conditions, loops, functions, classes, and everything else C++ has to offer.
EasyIn is meant to help with that first step.
It's small, header-only, and built around only a few functions.
The implementation is also simple enough that beginners can open easyin.hpp and see how it works.
Header-only
You only need to include:
#include "easyin.hpp"
The functions are declared inline, so the header can safely be included from multiple .cpp files.
For example:
inline bool input(auto &var, std::istream &in = std::cin)
and:
inline bool inputln(std::string &var, std::istream &in = std::cin)
EasyIn requires C++20 or newer.
The library itself doesn't require C++23, although you can combine it with std::print() and std::println() if your compiler supports them.
Final thoughts
C++ is a powerful language, but it can also be intimidating when you're starting out.
EasyIn isn't meant to change how C++ works.
It's just a small helper that makes one part of the learning process a little easier.
Instead of immediately worrying about the differences between:
std::cin
std::getline()
std::ws
clear()
ignore()
a beginner can start with:
input()
inputln()
and use:
inputAvailable()
when they need to handle retries safely.
Then, when they need more control, the normal C++ stream tools are still there.
If you're learning C++, or moving to C++ from something like Python, that is the problem I wanted EasyIn to help with.
Top comments (0)