This month’s Exercise is to create a program that converts weight measurements by using this format:
nnnFT
Where nnn
is a value, F
is the unit to convert from, and T
is the unit to convert to. This problem is more of an input-parsing exercise than a straight conversion.
For my solution, I use an if-else if-else structure to sift through the various permutations of K (kilos), P (pounds), and S (stone). The first step, however, is to pull out the relevant information.
To process the string I use the strtof() function. This function is far superior to the old atof() function; strtof() uses two pointers, illustrated in Figure 1.
The first pointer, input
, references the string containing the value — and the value must come first. The second pointer, which is the address of a pointer (convert
in my example), will hold the location of the first non-value character in the string, which comes in handy for plucking out the conversion characters.
(I don’t cover the strtof() function specifically in this blog, though I do cover its relative strtod() in this blog post.)
After input is read, this statement converts the value:
w = strtof(input,&convert);
Variable w
holds the floating point value stored in string input
, with pointer variable convert
holding the location of the next character after the value. To ensure that the input was valid, a test is performed on w:
if( w==0.0 && convert==input )
error_exit();
When the value returned by strtof() is zero and both pointers are equal, the input contained no value. The code exits with an error message (error_exit()) when true.
After converting and checking the value, another test is performed to ensure that two characters are typed after the value, where convert
is a pointer referencing the first character:
if( *convert=='\0' ||
*convert=='\n' ||
*(convert+1)=='\0' ||
*(convert+1)=='\n')
{
error_exit();
}
At this point, I’m assured that two characters are found after the value, so a series of tests are performed to examine these characters and output the proper results. If anything goes awry during these tests, control is thrust to the error_exit() function, which terminates the code.
Here is my solution:
2020_12-Exercise.c
#include <stdio.h> #include <stdlib.h> #include <ctype.h> void error_exit(void) { puts("Invalid input"); exit(1); } int main() { float w; char input[16]; char *r,*convert; /* intro text */ puts("Type a value to convert, suffixed by conversion types:"); puts("K - kilos, P - pounds, S - stones"); puts("Example: 2.0PK (convert 2.0 pounds to kilograms)"); printf("Convert: "); /* gather input */ r = fgets(input,16,stdin); if( r==NULL ) error_exit(); /* process input */ w = strtof(input,&convert); /* text for nothing input */ if( w==0.0 && convert==input ) error_exit(); /* confirm that conversion characters exist */ if( *convert=='\0' || *convert=='\n' || *(convert+1)=='\0' || *(convert+1)=='\n') { error_exit(); } /* kilo conversions */ if( toupper(*convert)=='K' ) { if( toupper( *(convert+1))=='P' ) printf("%.2f kilos is %.2f pounds\n",w,w*2.20462); else if( toupper( *(convert+1))=='S' ) printf("%.2f kilos is %.2f stone\n",w,w*0.157473); else error_exit(); } /* pounds conversions */ else if( toupper(*convert)=='P' ) { if( toupper( *(convert+1))=='K' ) printf("%.2f pounds is %.2f kilos\n",w,w*0.453592); else if( toupper( *(convert+1))=='S' ) printf("%.2f pounds is %.2f stone\n",w,w*0.0714286); else error_exit(); } /* stone conversions */ else if( toupper(*convert)=='S' ) { if( toupper( *(convert+1))=='K' ) printf("%.2f stone is %.2f kilos\n",w,w*6.35029); else if( toupper( *(convert+1))=='P' ) printf("%.2f stone is %.2f pounds\n",w,w*14.0); else error_exit(); } else error_exit(); return(0); }
The if-else if-else monster scours for permutations of K, P, and S. Then a nested if-else if-else structure scans for the other letter and handles bogus input. Conversions are made within the printf() statements that output the results. Various toupper() functions translate lowercase letters to uppercase.
Type a value to convert, suffixed by conversion types:
K - kilos, P - pounds, S - stones
Example: 2.0PK (convert 2.0 pounds to kilograms)
Convert: 103.5kp
103.50 kilos is 228.18 pounds
In the sample run above, 103.5 kilograms is converted into pounds: 228.18.
I hope your solution works and that proper output is generated.