Converting between different units of temperature 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 &lt;stdio.h&gt; /** standard io **/
#include &lt;stdlib.h&gt; /** exit(), atof and the lot **/
#include &lt;unistd.h&gt; /** 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 -&gt; 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 &gt; 273.1499 &amp;&amp; N &lt; 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);
}
Numerical consts are double, either add them eg as 5.0f or use double.
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 &lt;math.h&gt;

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) &lt; 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;
}