This is an implementation of a practice problem from cprogramming.com: Temperature Converter Challenge
The problem:
In this challenge, write a program that takes in three arguments, a start temperature (in Celsius), an end temperature (in Celsius) and a step size. Print out a table that goes from the start temperature to the end temperature, in steps of the step size; you do not actually need to print the final end temperature if the step size does not exactly match. You should perform input validation: do not accept start temperatures less than a lower limit (which your code should specify as a constant) or higher than an upper limit (which your code should also specify). You should not allow a step size greater than the difference in temperatures. (This exercise was based on a problem from C Programming Language).
The code:
#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
using namespace std;
const double LowestLimit = 0;
const double HighestLimit = 50000;
const string LowerLimitMessage = "Please enter a lower limit, limit >= 0: ";
struct UserInputs
{
public:
double LowerLimit = -1;
double UpperLimit = -1;
double StepAmount = -1;
};
stringstream GetSingleInput(const string message)
{
stringstream returnStream;
string input;
cout << message;
cin >> input;
returnStream << input;
return returnStream;
}
UserInputs GetUserInputs()
{
UserInputs parsedInputs;
auto LowerLimitStream = GetSingleInput(LowerLimitMessage);
while (!(LowerLimitStream >> parsedInputs.LowerLimit) || parsedInputs.LowerLimit < LowestLimit)
{
cout << "Invalid Lower Limit!\n";
LowerLimitStream = GetSingleInput(LowerLimitMessage);;
}
stringstream UpperLimitMessage;
UpperLimitMessage << "Please enter an upper limit, limit > "
<< parsedInputs.LowerLimit
<< ", limit <= "
<< HighestLimit
<< ": ";
auto UpperLimitStream = GetSingleInput(UpperLimitMessage.str());
while (!(UpperLimitStream >> parsedInputs.UpperLimit)
|| parsedInputs.UpperLimit > HighestLimit
|| parsedInputs.UpperLimit <= parsedInputs.LowerLimit)
{
cout << "Invalid Upper Limit!\n";
UpperLimitStream = GetSingleInput(UpperLimitMessage.str());
}
stringstream stepMessage;
stepMessage << "Please enter a step amount , step > "
<< LowestLimit
<< ", step <= "
<< (parsedInputs.UpperLimit - parsedInputs.LowerLimit)
<< ": ";
auto stepStream = GetSingleInput(stepMessage.str());
while (!(stepStream >> parsedInputs.StepAmount)
|| parsedInputs.StepAmount <= 0
|| parsedInputs.StepAmount > parsedInputs.UpperLimit - parsedInputs.LowerLimit)
{
cout << "Invalid Step Amount!\n";
stepStream = GetSingleInput(stepMessage.str());
}
return parsedInputs;
}
double CelsiusToFarenheit(const double celsius)
{
return celsius * 33.8;
}
int main()
{
auto inputs = GetUserInputs();
cout << "Celsius" << "\t\t\t" << "Farenheit" << "\n";
cout << "----------" << "\t\t" << "----------" << "\n";
cout.precision(9);
while (inputs.LowerLimit <= inputs.UpperLimit)
{
cout << fixed << inputs.LowerLimit << "\t\t" << CelsiusToFarenheit(inputs.LowerLimit) << "\n";
inputs.LowerLimit += inputs.StepAmount;
}
return 0;
}
I'm a C# developer who has been self learning C++. As a result I am likely making simple mistakes on structural design which don't feel odd in C#.
Any commentary would be appreciated, especially as to whether or not my method of checking the input is inefficient.
double CelsiusToFarenheit(const double celsius)
is weird to me. When dealing with function arguments I only useconst
if it refers to a reference or a pointer. Otherwise it sort of implies that you think changing the copied object passed to the function would change the original object. This is subjective however. \$\endgroup\$