\$\begingroup\$
\$\endgroup\$
The task is to convert a temperature in a list of Fahrenheit, Celsius, or Kelvin to the two other temperatures in the list.
Here is my code:
/*
* #define LANG C
*/
#include <stdio.h> /** standard io **/
#include <stdlib.h> /** exit(), atof and the lot **/
#include <unistd.h> /** needed for getopt() **/
/*** SYMBOIC CONSTANTS ***/
#define VERSION "1.0" /** version string array **/
#define HELP help(argv[0]) /** will insert this instead of help(argv[0]) every time **/
#define FLOATARG atof(optarg) /** atof is kind of vague, so a #define is better **/
#define TOVERH "FAHR\tCELSIUS\tKELVIN\n" /** just so I don't have to type it out ever time **/
#define OPTS "vk:f:c:h" /** I prefer a #define to this -> b:ull:s::hi:t: **/
/** For reference, an option followed by a double colon **/
/** signifies that it takes no arguments **/
/** while an option followed by one colon signifies **/
/** that it takes one argument. **/
static const char *ver = VERSION;
void help(char *s);
int check(float N) { /** check if kelvin temperature is celsius 0 **/
if(N > 273.1499 && N < 273.15001) { /** I had to set this limit. There is no other way. **/
return 1;
}
else {
return 0;
}
}
/*** Fahrenheit ***/
float FK(float F) {
return(((5.0 / 9.0) * (F - 32.0)) + 273.15);
}
float FC(float F) {
return((5.0 / 9.0) * (F - 32.0));
}
void printfahr(float F) {
printf(TOVERH);
printf("%4.3f\t%5.3f\t%5.3f\n", F, FC(F), FK(F));
}
/** Celsius **/
float CK(float C) {
return((C + 273.15));
}
float CF(float C) {
return((C * (9.0 / 5.0) - 32.0));
}
void printc(float C) {
printf(TOVERH);
printf("%4.3f\t%5.3f\t%5.3f\n", CF(C), C, CK(C));
}
/*** Kelvin ***/
float KC(float K) {
return(K - 273.15);
}
float KF(float K) {
return((K - 273.15) * (9.0 / 5.0) - 32.0);
}
void printk(float K) {
printf(TOVERH);
printf("%4.3f\t%5.3f\t%5.3f\n", KF(K), KC(K), K);
}
int main(int argc, char *argv[]) {
if(argc == 1) {
HELP;
exit(argc);
}
else {
char arg = '0円';
while((arg = getopt(argc, argv, OPTS)) != -1)
{
switch(arg) {
case 'c':
if(optarg == NULL)
{
HELP;
exit(1);
}
else {
printc(FLOATARG);
}
break;
case 'f':
if(optarg == NULL)
{
HELP;
exit(1);
}
else {
printfahr(FLOATARG);
}
break;
case 'h':
HELP;
break;
case 'k':
if(optarg == NULL)
{
HELP;
exit(1);
}
else {
if(check(FLOATARG) != 0)
{
printf(TOVERH);
printf("32.0\t0\t273.15\n");
}
else {
printk(FLOATARG);
}
}
break;
case 'v':
printf("%s\n", ver);
break;
default:
HELP;
break;
}
}
}
return 0;
}
void help(char *s) {
printf("Usage:\t%s [-c Celsius] [-f Fahrenheit] [-h] [-k Kelvin] [-v]\n", s);
}
Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Aug 11, 2017 at 21:03
1 Answer 1
\$\begingroup\$
\$\endgroup\$
1
- Numerical consts are
double
, either add them eg as 5.0f or usedouble
. - Define a constants for 0°C = 273.15K and also for Fahrenheit to Celsius conversation (avoid repeated magic constants 273.15, 9.0 / 5.0, 32.0).
- In
check
the distance from 273.15 is not symmetric, probably a typo. - The name
check
doesn't imply what is checked, meaningful names not limited to this function would be a recommended.
A modified version could include:
#include <math.h>
const double Celsius2KelvinShift = 273.15;
const double Fahrenheit2KCelsiusShift = 32.0;
const double Fahrenheit2CelsiusFactor = 5.0 / 9.0;
/** check if kelvin temperature is celsius 0 **/
int checkIf0Celsius(double N)
{
const double tol = 0.001; /** I had to set this limit. There is no other way. **/
return fabs(N - Celsius2KelvinShift) < tol;
}
/*** Fahrenheit ***/
double Fahrenheit2Kelvin(double F)
{
return Fahrenheit2CelsiusFactor * (F - Fahrenheit2KCelsiusShift) + Celsius2KelvinShift;
}
double Fahrenheit2Celsius(double F)
{
return Fahrenheit2CelsiusFactor * (F - Fahrenheit2KCelsiusShift);
}
/** Celsius **/
double Celsius2Kelvin(double C)
{
return C + Celsius2KelvinShift;
}
double Celsius2Fahrenheit(double C)
{
return C / Fahrenheit2CelsiusFactor - Fahrenheit2KCelsiusShift;
}
/*** Kelvin ***/
double Kelvin2Celsius(double K)
{
return K - Celsius2KelvinShift;
}
double Kelvin2Fahrenheit(double K) {
return (K - Celsius2KelvinShift) / Fahrenheit2CelsiusFactor - Fahrenheit2KCelsiusShift;
}
answered Aug 12, 2017 at 17:28
-
\$\begingroup\$ Good answer. As for the asymmetry, I set it because I wasn't sure how far to go; I saw that 273.15 as a float was in fact being stored as 273.1994 or something like that; I originally intended to ask on SO why this was the case, but... I got a 6-Month ban because too many people downvoted my questions there :/ \$\endgroup\$Distant Graphics– Distant Graphics2017年08月12日 18:24:26 +00:00Commented Aug 12, 2017 at 18:24
lang-c