Read data from the user, catch invalid input, read a line of text and format the output; with an Ohm's law calculator.
So far we have only written to the screen. Real programs take data from the user. In C++ reading is done with std::cin, and it relies on the >> operator, the opposite of the << operator we used for printing.
Ohm's law calculator
Let's take the voltage and resistance from the user and calculate the current and the power.
#include <iostream>
int main() {
double volt = 0.0;
double resistance = 0.0;
std::cout << "Voltage (V): ";
std::cin >> volt;
std::cout << "Resistance (ohm): ";
std::cin >> resistance;
if (!std::cin || resistance <= 0.0) {
std::cout << "Invalid input!\n";
return 1;
}
double current = volt / resistance;
std::cout << "Current: " << current << " A\n";
std::cout << "Power: " << volt * current << " W\n";
return 0;
}
If we run the program and enter 12 and 4:
Voltage (V): 12
Resistance (ohm): 4
Current: 3 A
Power: 36 W
The line std::cin >> volt; reads the text up to a space or the end of the line and converts it to the type of the volt variable. You can also enter both values on one line: std::cin >> volt >> resistance;. It makes no difference whether there is a space or an Enter between them.
Catching invalid input
If the user types "abc" instead of a number, std::cin goes into a failed state. You can check for this with if (!std::cin). In the check we also filtered out physically meaningless values: if the resistance is zero or negative, we don't divide. We will cover conditions (if) in detail two lessons from now; for now, read it as "if the condition is true, run the lines inside".
If you want to continue after an error, you have to repair the stream:
std::cin.clear(); // clear the error state
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // discard the rest of the line
The second line needs #include <limits>.
Reading text with spaces: getline
std::cin >> name reads only the first word. To get a full line such as "John Smith", you use std::getline. However, if you call getline right after reading a number, it reads the Enter character left over after the number and you get an empty string. The fix is to put an ignore in between:
#include <iostream>
#include <limits>
#include <string>
int main() {
int age = 0;
std::string name;
std::cout << "Age: ";
std::cin >> age;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << "Full name: ";
std::getline(std::cin, name);
std::cout << name << " is " << age << " years old\n";
return 0;
}
Formatting the output
The <iomanip> header lets you arrange the output:
std::fixedandstd::setprecision(n): set the number of decimal places.std::setw(n): reserves a field at least n characters wide for the next value; very handy when printing tables.std::leftandstd::right: choose the alignment.
For example, std::cout << std::fixed << std::setprecision(2) << 3.14159; prints 3.14. setprecision is sticky; once set, it also affects the numbers that follow.
std::cerr is a separate output stream for error messages. When you redirect a program's output to a file (program > result.txt), the normal output goes to the file but the error messages stay on the screen. In large projects this separation is very useful.
Never trust data that comes from the user. Division by zero, a negative resistance or letters typed in can lead the program to a wrong result or a crash. Validate every input.
Try it yourself
- Change the calculator so that it finds the voltage when the current and resistance are entered.
- Print the results with two decimal places.
- Read a name and an age from the user and print them in the form "Ahmet is 25 years old".
- Try typing letters instead of a number and see the program say "Invalid input!".
// Mini quiz
Click an option; you will see right away, with the reason, whether it is correct or not.
Mark it when you finish: your progress is saved and you earn +20 XP.
Tip: ← → keys let you move between lessons.