stevepedwards.com/DebianAdmin linux mint IT admin tips info

Practical C Programming – Switch and Nested Switches Example

I wanted to explore a further level of switching to implement a sub level menu within a main switch option, by adding to my Imperial to metric units converter. This allows extra functionality to a handy program - a two way units conversion choice.  

Although trial and error placement is slow, it does let you think more about a program's operation, so help the learning curve, rather than just google an answer. The first working version program code is:

/*units converter for dist, vol or mass*/
#include <stdio.h>
float km; /*= 1;*/
float miles; /*= 1.60934 * km ;*/
float litre; /*= 1;*/
float pints; /*= (1.75975 / litre);*/
float gallons; /*= (8 * pints);*/
float kg; /*= 1;*/
float lb; /* = (2.204622 * kg);*/
char line[10]; /*input value array space */
char operator; /* menu operator the user specified */
float value; /* input value the user specified */
float result;
int main()
{
while (1)
{
printf("program to convert Imperial units to metric. Enter menu option: \n");
printf("1: km to miles\n");
printf("2: litres to pints\n");
printf("3: kg to pounds\n");
printf("q: quit\n");
fgets(line, sizeof(line), stdin);
sscanf(line, "%c", &operator);

if ((operator == 'q') || (operator == 'Q'))
break;
switch (operator)
{
case '1':
printf("1: convert km to miles. Enter km value: ");
fgets(line, sizeof(line), stdin);
sscanf(line, "%f", &value);
result = value / 1.60934;
printf("%f km is %0.3f miles \n\n", value, result);
break;

case '2':
printf("1: convert litres to pints. Enter litre value: ");
fgets(line, sizeof(line), stdin);
sscanf(line, "%f", &value);
result = value * 1.75975;
gallons = result/8;
printf("%0.3f litres is %0.3f pints or %0.3f gallons\n\n", value, result, gallons );
break;

case '3':
printf("3: convert kg to pounds. Enter kg value: ");
fgets(line, sizeof(line), stdin);
sscanf(line, "%f", &value);
result = value * 2.204622;
printf("%0.3f kg is %0.3f pounds \n\n", value, result);
break;

default:
{
printf("Invalid key, try again! %c\n\n", operator);
break;
}
}
}
printf("\n"); /*tidy cmd line*/
return (0);
}

unitconverter.png

This offers only metric to Imperial units conversion at present:

$ ./unitsconverter
program to convert Imperial units to metric. Enter menu option:
1: km to miles
2: litres to pints
3: kg to pounds
q: quit
1
1: convert km to miles. Enter km value: 1
1.000000 km is 0.621 miles

program to convert Imperial units to metric. Enter menu option:
1: km to miles
2: litres to pints
3: kg to pounds
q: quit
w
Invalid key, try again! w

program to convert Imperial units to metric. Enter menu option:
1: km to miles
2: litres to pints
3: kg to pounds
q: quit
q

Now it was just finding the correct format using clues from the above switch cases - with breaks in the right places - to make the extra nested switch options behave as desired. The first working case 1 sub menu code is shown below so you can see how it enters the first case option and breaks out to the main menu after either choice is completed:

int main()
{
while (1)
{
printf("program to convert Imperial units to metric. Enter menu option: \n");
printf("1: km to miles\n");
printf("2: litres to pints\n");
printf("3: kg to pounds\n");
printf("q: quit\n");
fgets(line, sizeof(line), stdin);
sscanf(line, "%c", &operator);

if ((operator == 'q') || (operator == 'Q'))
break;
switch (operator)
{
case '1':
printf("Want to (k) convert km to miles or (m) miles to km?: ");
fgets(line, sizeof(line), stdin);
sscanf(line, "%c", &operator);
switch (operator)
{
case 'k':
printf("k: convert km to miles. Enter km value: ");
fgets(line, sizeof(line), stdin);
sscanf(line, "%f", &value);
result = value / 1.60934;
printf("%f km is %0.3f miles \n\n", value, result);
break;
case 'm':
printf("m: convert miles to km. Enter miles value: ");
fgets(line, sizeof(line), stdin);
sscanf(line, "%f", &value);
result = value * 1.60934;
printf("%f m is %0.3f km \n\n", value, result);
break;
}
break;
case '2':
printf("2: convert litres to pints. Enter litre value: ");
fgets(line, sizeof(line), stdin);
sscanf(line, "%f", &value);
result = value * 1.75975;
gallons = result/8;
printf("%0.3f litres is %0.3f pints or %0.3f gallons\n\n", value, result, gallons );
break;

This shows both extra options working as required:

$ ./unitsconverter2
program to convert Imperial units to metric. Enter menu option:
1: km to miles
2: litres to pints
3: kg to pounds
q: quit
1
Want to (k) convert km to miles or (m) miles to km?: k
k: convert km to miles. Enter km value: 1
1.000000 km is 0.621 miles

program to convert Imperial units to metric. Enter menu option:
1: km to miles
2: litres to pints
3: kg to pounds
q: quit
1
Want to (k) convert km to miles or (m) miles to km?: m
m: convert miles to km. Enter miles value: 1
1.000000 m is 1.609 km

program to convert Imperial units to metric. Enter menu option:
1: km to miles
2: litres to pints
3: kg to pounds
q: quit
Invalid key, try again! w

program to convert Imperial units to metric. Enter menu option:
1: km to miles
2: litres to pints
3: kg to pounds
q: quit
q

unitsconv2.c.png

Now it's just a case of pasting the same format to the other 2 options and re-arranging the formulae and units.

The exit beaks from the final main case 3 have to be correctly placed with {}'s to account for the default already in place:

case3conv.png

Comments are closed.

Post Navigation