Reputation: 346
I have the following simple program to read two integer inputs and output their quotient:
static int getQuotient(int v1, int v2) {
if (v2 == 0)
throw runtime_error("Error: cannot divide by zero.");
return v1 / v2;
}
int main()
{
int v1, v2;
cout << "Enter two integers." << endl;
while(cin >> v1 >> v2) {
int quotient;
try {
quotient = getQuotient(v1, v2);
}
catch (runtime_error err) {
cout << err.what() << "\n" << "Please try again." << endl;
continue;
}
cout << v1 << " / " << v2 << " = " << quotient << endl;
}
}
As is, the program returns to the top of the while
loop in main()
when it encounters zero division. What I would like to do is have something like this in place of the current catch statement:
catch(runtime_error err) {
cout << err.what() << endl;
cout << "Enter a new value for v2." << endl;
cin >> v2;
continue;
}
So that the a new value is stored in v2
and the loop restarts. However, when the loop restarts new values are read into v1
and v2
which I don't want. Is there a way (besides goto
) to return to the top of the loop without checking the condition? I know this is a specific use case but if there's an idiomatic way to solve this I'd rather know it.
Upvotes: 0
Views: 94
Reputation: 29955
If you can, moving the input validation to a different routine of itself could improve the code:
#include <iostream>
#include <optional>
#include <utility>
std::optional<std::tuple<int, int>>
get_v1_and_v2(std::istream& is = std::cin, std::ostream& os = std::cout)
{
os << "Enter two integers.\n";
int v1;
if (!(is >> v1))
return std::nullopt;
int v2;
while (true) {
if (!(is >> v2))
return std::nullopt;
if (!v2)
os << "v2 cannot be zero. Please try again.\n";
else
return std::tuple<int, int>{ v1, v2 };
}
}
int
main()
{
while (auto const input = get_v1_and_v2()) {
auto const [v1, v2] = *input;
std::cout << v1 << " / " << v2 << " = " << (v1/v2) << '\n';
}
}
Upvotes: 0
Reputation:
To avoid the record of input sometimes, you can use a bool value like this :
int main()
{
int v1, v2;
cout << "Enter two integers." << endl;
bool repeat_without_input = false;
while(repeat_without_input == true || cin >> v1 >> v2) {
repeat_without_input = false;
int quotient;
try {
quotient = getQuotient(v1, v2);
}
catch (runtime_error err) {
cout << err.what() << "\n" << "Please try again." << endl;
repeat_without_input = true;
continue;
}
cout << v1 << " / " << v2 << " = " << quotient << endl;
}
}
Upvotes: 0
Reputation: 97918
Maybe something like this:
while(cin >> v1) {
int quotient;
while (true) {
cin >> v2;
try {
quotient = getQuotient(v1, v2);
}
catch (runtime_error err) {
cout << err.what() << "\n" << "Please try again." << endl;
continue;
}
break;
}
cout << v1 << " / " << v2 << " = " << quotient << endl;
}
Upvotes: 5