stevepedwards.com/DebianAdmin linux mint IT admin tips info

Chapter 8 Notes – Practical C Programming, 3rd Edition By Steve Oualline

Chapter 8 describes additional control statements. Included are while, break, and continue. The switch statement is discussed in detail.

while loop example:

#include <stdio.h>

int total; /* total of all the numbers */

int current; /* current value from the user */

int counter; /* while loop counter */

char line[80]; /* Line from keyboard */

int main() {

total = 0;

counter = 0;

while (counter < 5) {

printf("Number? ");

fgets(line, sizeof(line), stdin);

sscanf(line, "%d", &current);

total += current;

++counter;

}

printf("The grand total is %d\n", total);

return (0);

}

$ ./total

Number? 1

Number? 2

Number? 3

Number? 4

Number? 5

The grand total is 15

Same with for loop:

#include <stdio.h>

int total;

/* total of all the numbers */

int current; /* current value from the user */

int counter; /* for loop counter */

char line[80]; /* Input from keyboard */

int main() {

total = 0;

for (counter = 0; counter < 5; ++counter) /*value of counter, starts 0 but is 4 at end of this loop */

{

printf("Number? "); /*user prompt*/

fgets(line, sizeof(line), stdin);

sscanf(line, "%d", &current);

total += current; /* running total starting at 0; user input current number is added to it each loop*/

}

printf("The grand total is %d\n", total); /*total sum of all inputs at end of loop 5*/

return (0);

}

Note that counter goes from to 4. Ordinarily, you count five items as 1, 2, 3, 4, 5; but you will perform much better in C if you change your thinking to zero -based counting and then count five items as 0, 1, 2, 3, 4. (One-based counting is one of the main ca uses of array overflow errors.

Similarities between "while" and "for":

Question 8-1 : When Example 8 -3 runs, it prints:

Celsius:101 Fahrenheit:213 and nothing more. Why?

/*cent.c*/

#include <stdio.h>

/** This program produces a Celsius to Fahrenheit conversion

*chart for the numbers 0 to 100.*/

/* The current Celsius temperature we are working with */

int celsius;

int main()

{

for (celsius = 0; celsius <= 100; ++celsius);

printf("Celsius:%d Fahrenheit:%d\n", celsius, (celsius * 9) / 5 + 32);

return (0);

}

/*centdebug.c*/

#include <stdio.h>

/** This program produces a Celsius to Fahrenheit conversion

*chart for the numbers 0 to 100.*/

/* The current Celsius temperature we are working with */

int celsius;

int main()

{

for (celsius = 0; celsius <= 100; ++celsius)

{ /*WAS MISSING { so did not loop*/

printf("Celsius:%d ", celsius); /* debug printf to check initial celsius value */

printf("Fcalcd:%d ", (celsius * 9) / 5 + 32); /* debug printf to check integer division 0/5=0 */

printf("Celsius:%d Fahrenheit:%d\n", celsius, (celsius * 9) / 5 + 32);

} /* WAS MISSING } */

return (0);

}

$ ./centdebug

Celsius:0 Fcalcd:32 Celsius:0 Fahrenheit:32

Celsius:1 Fcalcd:33 Celsius:1 Fahrenheit:33

Celsius:2 Fcalcd:35 Celsius:2 Fahrenheit:35

Celsius:3 Fcalcd:37 Celsius:3 Fahrenheit:37

Celsius:4 Fcalcd:39 Celsius:4 Fahrenheit:39

Celsius:5 Fcalcd:41 Celsius:5 Fahrenheit:41

Celsius:6 Fcalcd:42 Celsius:6 Fahrenheit:42

Celsius:7 Fcalcd:44 Celsius:7 Fahrenheit:44

Celsius:8 Fcalcd:46 Celsius:8 Fahrenheit:46

Celsius:9 Fcalcd:48 Celsius:9 Fahrenheit:48

Celsius:10 Fcalcd:50 Celsius:10 Fahrenheit:50

Celsius:11 Fcalcd:51 Celsius:11 Fahrenheit:51

Celsius:12 Fcalcd:53 Celsius:12 Fahrenheit:53

Celsius:13 Fcalcd:55 Celsius:13 Fahrenheit:55

Celsius:14 Fcalcd:57 Celsius:14 Fahrenheit:57

Celsius:15 Fcalcd:59 Celsius:15 Fahrenheit:59

Celsius:16 Fcalcd:60 Celsius:16 Fahrenheit:60

Celsius:17 Fcalcd:62 Celsius:17 Fahrenheit:62

Celsius:18 Fcalcd:64 Celsius:18 Fahrenheit:64

Celsius:19 Fcalcd:66 Celsius:19 Fahrenheit:66

Celsius:20 Fcalcd:68 Celsius:20 Fahrenheit:68

Celsius:21 Fcalcd:69 Celsius:21 Fahrenheit:69

Celsius:22 Fcalcd:71 Celsius:22 Fahrenheit:71

Celsius:23 Fcalcd:73 Celsius:23 Fahrenheit:73

Celsius:24 Fcalcd:75 Celsius:24 Fahrenheit:75

Celsius:25 Fcalcd:77 Celsius:25 Fahrenheit:77

Celsius:26 Fcalcd:78 Celsius:26 Fahrenheit:78

Celsius:27 Fcalcd:80 Celsius:27 Fahrenheit:80

Celsius:28 Fcalcd:82 Celsius:28 Fahrenheit:82

Celsius:29 Fcalcd:84 Celsius:29 Fahrenheit:84

Celsius:30 Fcalcd:86 Celsius:30 Fahrenheit:86

Celsius:31 Fcalcd:87 Celsius:31 Fahrenheit:87

Celsius:32 Fcalcd:89 Celsius:32 Fahrenheit:89

Celsius:33 Fcalcd:91 Celsius:33 Fahrenheit:91

Celsius:34 Fcalcd:93 Celsius:34 Fahrenheit:93

Celsius:35 Fcalcd:95 Celsius:35 Fahrenheit:95

Celsius:36 Fcalcd:96 Celsius:36 Fahrenheit:96

Celsius:37 Fcalcd:98 Celsius:37 Fahrenheit:98

Celsius:38 Fcalcd:100 Celsius:38 Fahrenheit:100

Celsius:39 Fcalcd:102 Celsius:39 Fahrenheit:102

Celsius:40 Fcalcd:104 Celsius:40 Fahrenheit:104

Celsius:41 Fcalcd:105 Celsius:41 Fahrenheit:105

Celsius:42 Fcalcd:107 Celsius:42 Fahrenheit:107

Celsius:43 Fcalcd:109 Celsius:43 Fahrenheit:109

Celsius:44 Fcalcd:111 Celsius:44 Fahrenheit:111

Celsius:45 Fcalcd:113 Celsius:45 Fahrenheit:113

Celsius:46 Fcalcd:114 Celsius:46 Fahrenheit:114

Celsius:47 Fcalcd:116 Celsius:47 Fahrenheit:116

Celsius:48 Fcalcd:118 Celsius:48 Fahrenheit:118

Celsius:49 Fcalcd:120 Celsius:49 Fahrenheit:120

Celsius:50 Fcalcd:122 Celsius:50 Fahrenheit:122

Celsius:51 Fcalcd:123 Celsius:51 Fahrenheit:123

Celsius:52 Fcalcd:125 Celsius:52 Fahrenheit:125

Celsius:53 Fcalcd:127 Celsius:53 Fahrenheit:127

Celsius:54 Fcalcd:129 Celsius:54 Fahrenheit:129

Celsius:55 Fcalcd:131 Celsius:55 Fahrenheit:131

Celsius:56 Fcalcd:132 Celsius:56 Fahrenheit:132

Celsius:57 Fcalcd:134 Celsius:57 Fahrenheit:134

Celsius:58 Fcalcd:136 Celsius:58 Fahrenheit:136

Celsius:59 Fcalcd:138 Celsius:59 Fahrenheit:138

Celsius:60 Fcalcd:140 Celsius:60 Fahrenheit:140

Celsius:61 Fcalcd:141 Celsius:61 Fahrenheit:141

Celsius:62 Fcalcd:143 Celsius:62 Fahrenheit:143

Celsius:63 Fcalcd:145 Celsius:63 Fahrenheit:145

Celsius:64 Fcalcd:147 Celsius:64 Fahrenheit:147

Celsius:65 Fcalcd:149 Celsius:65 Fahrenheit:149

Celsius:66 Fcalcd:150 Celsius:66 Fahrenheit:150

Celsius:67 Fcalcd:152 Celsius:67 Fahrenheit:152

Celsius:68 Fcalcd:154 Celsius:68 Fahrenheit:154

Celsius:69 Fcalcd:156 Celsius:69 Fahrenheit:156

Celsius:70 Fcalcd:158 Celsius:70 Fahrenheit:158

Celsius:71 Fcalcd:159 Celsius:71 Fahrenheit:159

Celsius:72 Fcalcd:161 Celsius:72 Fahrenheit:161

Celsius:73 Fcalcd:163 Celsius:73 Fahrenheit:163

Celsius:74 Fcalcd:165 Celsius:74 Fahrenheit:165

Celsius:75 Fcalcd:167 Celsius:75 Fahrenheit:167

Celsius:76 Fcalcd:168 Celsius:76 Fahrenheit:168

Celsius:77 Fcalcd:170 Celsius:77 Fahrenheit:170

Celsius:78 Fcalcd:172 Celsius:78 Fahrenheit:172

Celsius:79 Fcalcd:174 Celsius:79 Fahrenheit:174

Celsius:80 Fcalcd:176 Celsius:80 Fahrenheit:176

Celsius:81 Fcalcd:177 Celsius:81 Fahrenheit:177

Celsius:82 Fcalcd:179 Celsius:82 Fahrenheit:179

Celsius:83 Fcalcd:181 Celsius:83 Fahrenheit:181

Celsius:84 Fcalcd:183 Celsius:84 Fahrenheit:183

Celsius:85 Fcalcd:185 Celsius:85 Fahrenheit:185

Celsius:86 Fcalcd:186 Celsius:86 Fahrenheit:186

Celsius:87 Fcalcd:188 Celsius:87 Fahrenheit:188

Celsius:88 Fcalcd:190 Celsius:88 Fahrenheit:190

Celsius:89 Fcalcd:192 Celsius:89 Fahrenheit:192

Celsius:90 Fcalcd:194 Celsius:90 Fahrenheit:194

Celsius:91 Fcalcd:195 Celsius:91 Fahrenheit:195

Celsius:92 Fcalcd:197 Celsius:92 Fahrenheit:197

Celsius:93 Fcalcd:199 Celsius:93 Fahrenheit:199

Celsius:94 Fcalcd:201 Celsius:94 Fahrenheit:201

Celsius:95 Fcalcd:203 Celsius:95 Fahrenheit:203

Celsius:96 Fcalcd:204 Celsius:96 Fahrenheit:204

Celsius:97 Fcalcd:206 Celsius:97 Fahrenheit:206

Celsius:98 Fcalcd:208 Celsius:98 Fahrenheit:208

Celsius:99 Fcalcd:210 Celsius:99 Fahrenheit:210

Celsius:100 Fcalcd:212 Celsius:100 Fahrenheit:212

Seven.c

/*seven.c*/

#include <stdio.h>

char line[100]; /* line of input */

int seven_count; /* number of 7s in the data */

int data[5]; /* the data to count 3 and 7 in */

int three_count; /* the number of 3s in the data */

int index; /* index into the data */

int main()

{

seven_count = 0;

three_count = 0;

printf("Enter 5 numbers\n");

fgets(line, sizeof(line), stdin);

sscanf(line, "%d %d %d %d %d", &data[1], &data[2], &data[3], &data[4], &data[5]);

for (index = 1; index <= 5; ++index)

{

if (data[index] == 3)

++three_count;

if (data[index] == 7)

++seven_count;

}

printf("Threes %d Sevens %d\n",three_count, seven_count);

return (0);

}

When we run this program with the data 3 7 3 0 2, the results are:

Threes 4 Sevens 1

(Your results may vary.)

When run:

$ gcc -o seven seven.c

seven.c:7:5: warning: built-in function ‘index’ declared as non-function [enabled by default]

int index; /* index into the data */

^

stevee@AMDA8 ~/Cprogs/calc1 $ ./seven

Enter 5 numbers

37302

Threes 0 Sevens 0

WHY? Data array starts at 0 not 1, so first digit 3 goes into array 0; 7 in1; 3 in 2; 0 in 3; 2 in 4; \n in 5...leaving no room for \0…?

&data[1], &data[2], &data[3], &data[4], &data[5]);

7 3 0 2 \n

Using printf("1=%d,2=%d,3=%d,4=%d,5=%d", data[1],data[2],data[3],data[4],data[5]); to see what data is actually going into each array, I used a debug idea:

/*sevendebug.c*/

#include <stdio.h>

char line[100]; /* line of input */

int seven_count; /* number of 7s in the data */

int data[5]; /* the data to count 3 and 7 in */

int three_count; /* the number of 3s in the data */

int index; /* index into the data */

int main()

{

seven_count = 0;

three_count = 0;

printf("Enter 5 numbers\n");

fgets(line, sizeof(line), stdin);

sscanf(line, "%d %d %d %d %d", &data[1], &data[2], &data[3], &data[4], &data[5]);

for (index = 1; index <= 5; ++index)

{

printf("D1=%d, D2=%d, D3=%d, D4=%d, D5=%d\n", data[1],data[2],data[3],data[4],data[5]);

if (data[index] == 3)

++three_count;

if (data[index] == 7)

++seven_count;

}

printf("Threes %d Sevens %d\n",three_count, seven_count);

return (0);

}

This output:

$ ./sevendebug

Enter 5 numbers

33333

D1=33333, D2=0, D3=0, D4=0, D5=0

D1=33333, D2=0, D3=0, D4=0, D5=0

D1=33333, D2=0, D3=0, D4=0, D5=0

D1=33333, D2=0, D3=0, D4=0, D5=0

D1=33333, D2=0, D3=0, D4=0, D5=0

Threes 0 Sevens 0

stevee@AMDA8 ~/Cprogs/calc1 $ ./sevendebug

Enter 5 numbers

77777

D1=77777, D2=0, D3=0, D4=0, D5=0

D1=77777, D2=0, D3=0, D4=0, D5=0

D1=77777, D2=0, D3=0, D4=0, D5=0

D1=77777, D2=0, D3=0, D4=0, D5=0

D1=77777, D2=0, D3=0, D4=0, D5=0

Threes 0 Sevens 0

It seems all the numbers are going into one index array at the first loop only, not a separate array for each digit, so the loop reads 0s only after the first go. It also shows that the 3 and 7 counters CAN'T work either if all 3s or 7s are input, as there is not a single digit, but 5 in D1 only.

It's to do with space separation of the input chars to stop them all going into array 0 only…but not what he meant in the PDF re "index <= 5" etc. as this gcc vers works with that AND the incorrect array values 1-5, for 0-4!

/*5sevendebug.c*/

#include <stdio.h>

char line[100]; /* line of input */

int seven_count; /* number of 7s in the data */

int data[5]; /* the data to count 3 and 7 in */

int three_count; /* the number of 3s in the data */

int index; /* index into the data */

int main()

{

seven_count = 0;

three_count = 0;

printf("Enter 5 SPACE SEPARATED single digits!!\n");

fgets(line, sizeof(line), stdin);

sscanf(line, "%d %d %d %d %d", &data[1], &data[2], &data[3], &data[4], &data[5]);

for (index = 1; index <= 5; ++index)

{

printf("D1=%d, D2=%d, D3=%d, D4=%d, D5=%d\n", data[1],data[2],data[3],data[4],data[5]);

if (data[index] == 3)

++three_count;

if (data[index] == 7)

++seven_count;

}

printf("Threes %d Sevens %d\n",three_count, seven_count);

return (0);

}

$ ./sevendebug

Enter 5 SPACE SEPARATED single digits!!

3 3 3 7 7

D1=3, D2=3, D3=3, D4=7, D5=7

D1=3, D2=3, D3=3, D4=7, D5=7

D1=3, D2=3, D3=3, D4=7, D5=7

D1=3, D2=3, D3=3, D4=7, D5=7

D1=3, D2=3, D3=3, D4=7, D5=7

Threes 3 Sevens

When run with his original 3 7 3 0 2, I get the right answer – don't know what he's on about “results may vary..”. Why? it works!! Made me think about it I guess...and the spaced input was used in the triangle “width height” example.

The switch statement is similar to a chain of if/else statements. The general form of a switch statement is:

switch

( expression

case

) {

constant1 :

statement

. . . .

break ;

case

constant2 :

statement

. . . .

/* Fall through */

default:

statement

. . . .

break ;

case

constant3 :

statement

. . . .

break ;

}

The switch statement evaluates the value of an expression and branches to one of the case labels. Duplicate labels are not allowed, so only one case will be selected.

The expression must evaluate an integer, character, or enumeration.

The case labels can be in any order and must be constants. The default label can be put anywhere in the switch. No two case labels can have the same value.

When C sees a switch statement, it evaluates the expression and then looks for a matching case label. If none is found, the default label is used. If no default is found, the statement does nothing.

if (operator == '+') {

result += value;

} else if (operator == '-') {

result -= value;

} else if (operator == '*') {

result *= value;

} else if (operator == '/') {

if (value == 0) {

printf("Error:Divide by zero\n");

printf("

operation ignored\n");

} else

result /= value;

}

else {

printf("Unknown operator %c\n", operator);

}

This section of code can easily be rewritten as a switch statement. In this switch , we use a different case for each operation. The default clause takes care of all the illegal operators.

Rewriting our program using a switch statement makes it not only simpler, but

easier to read. Our revised calc program is shown:

/*calc3.c*/

#include <stdio.h>

char line[100]; /* line of text from input */

int result; /* the result of the calculations */

char operator; /* operator the user specified */

int value; /* value specified after the operator */

int main()

{

result = 0; /* initialize the result */

/* loop forever (or until break reached) */

while (1)

{

printf("Result: %d\n", result);

printf("Enter operator and number: ");

fgets(line, sizeof(line), stdin);

sscanf(line, "%c %d", &operator, &value);

if ((operator == 'q') || (operator == 'Q'))

break;

switch (operator)

{

case '+':

result += value;

break;

case '-':

result -= value;

break;

case '*':

result *= value;

break;

case '/':

if (value == 0)

{

printf("Error:Divide by zero\n");

printf("operation ignored\n");

}

else

result /= value;

break;

default:

printf("Unknown operator %c\n", operator);

break;

}

}

return (0);

}

$ ./calc3

Result: 0

Enter operator and number: +1

Result: 1

Enter operator and number: *5

Result: 5

Enter operator and number: -2

Result: 3

Enter operator and number: /1

Result: 3

Enter operator and number: +1.5 FLOATS NOT WORKING CORRECTLY YET...

Result: 4

Enter operator and number: Q

You cannot determine if the program is supposed

to fall through from case 0 to case 1, or if the programmer forgot to put in a break

statement. In order to clear up this confusion, a case section should always end

with a break statement or the comment /* Fall through */, as shown in the

following example:

/* a better example of programming */

switch (control) {

case 0:

printf("Reset\n");

/* Fall through */

case 1:

printf("Initializing\n");

break;

case 2:

printf("Working\n");

}

Because case 2 is last, it doesn't need a break statement. A break would cause the program to skip to the end of the switch, and we're already there.

If we always put in a break statement, we don't have to worry about whether or not it is really needed.

/* Almost there */

switch (control) {

case 0:

printf("Reset\n");

/* Fall through */

case 1:

printf("Initializing\n");

break;

case 2:

printf("Working\n");

break;

}

Finally, we ask the question: what happens when control == 5? In this case,

because no matching case or default clause exists, the entire switch statement is

skipped.

In this example, the programmer did not include a default statement because

control will never be anything but 0, 1, or 2. However, variables can get assigned

strange values, so we need a little more defensive programming, as shown in the

following example:

/* The final version */

switch (control) {

case 0:

printf("Reset\n");

/* Fall through */

case 1:

printf("Initializing\n");

break;

case 2:

printf("Working\n");

break;

default:

printf(

"Internal error, control value (%d) impossible\n",

control);

break;

}

Although a default is not required, it should be put in every switch. Even though the default may be:

default:

/* Do nothing */

break;

it should be included. This method indicates, at the very least, that you want to ignore out-of-range data.

switch, break, and continue

The break statement has two uses. Used inside a switch , break causes the program to go to the end of the switch.

Inside a for or while loop, break causes a loop exit. The continue statement is valid only inside a loop.

Continue will cause the program to go to the top of the loop. Figure 8-2 illustrates both continue and break inside a switch statement.

The program in Figure 8 -2 is designed to convert an integer with a number of different formats into different bases. If you want to know the value of an octal number, you would enter o ( for octal) and the number. The command q is used to quit the program. For example:

Enter conversion and number: o 55

Result is 45

Enter conversion and number: q

Debug these typos copied from above – good practise to write out..:

/*converter.c*/

#include <stdio.h>

int number; /* number to convert */

char type; /* conversion type to do */

char line[80]; /* Line from keyboard */

int main()

{

while {1}

printf("Enter Conversion and Number: ");

fgets(line, sizeof(line), stdin);

sscanf(line, "%c", &type);

if {(type == q || type == Q)}

break;

switch (type)

{

case 'o':

case 'O': /*Octal conv*/

sscanf(line, "%c %o", &type, &number);

break;

case 'x':

case 'X': /*Hex conv*/

sscanf(line, "%c %x", &type, &number);

break;

case 'd':

case 'D': /*Decimal conv */

sscanf(line, "%c %d", &type, &number);

break;

case '?':

case 'h': /* Help */

printf("Letter Conversion\n ");

printf(" o Octal\n ");

printf(" x Hex\n ");

printf(" d Dec\n ");

printf(" q Quit prog\n ");

/*Dont print the number*/

continue;

default:

printf("Type ? or h for help\n");

/*Dont print the number*/

continue;

}

printf("Result is: %d\n", number);

return (0);

}

Working Code:

Basic Test Plan for Converter.c:

a) Enter all valid options in order of cases with same test number = o 11 (=dec9); x 11 (=dec17); d 11 (=dec11).

b) Check Help: ?/h/H

c) Check “continue” function of the switch ignores non option input chars i.e. NOT “qoxdh?QOXDH”

d) Test exit: q,Q, CtrlC

$ ./converter

Enter Conversion and [SPACE] Number: o 11

Result is: 9

Enter Conversion and [SPACE] Number: x 11

Result is: 17

Enter Conversion and [SPACE] Number: d 11

Result is: 11

Enter Conversion and [SPACE] Number: ?

Letter Conversion

o Octal

x Hex

d Dec

q Quit prog

Enter Conversion and [SPACE] Number: h

Letter Conversion

o Octal

x Hex

d Dec

q Quit prog

Enter Conversion and [SPACE] Number: q

stevee@AMDA8 ~/Cprogs/calc1 $ ./converter

Enter Conversion and [SPACE] Number: d dgwdf

Result is: 0

Enter Conversion and [SPACE] Number: s 12

Type ? or h for help

Enter Conversion and [SPACE] Number: w

Type ? or h for help

Enter Conversion and [SPACE] Number: d

Result is: 0

Enter Conversion and [SPACE] Number: j

Type ? or h for help

Exercise 8-1 : Print a **&&^$$ e.g:

/*lines*/

#include <stdio.h>

int main()

{

printf("+-------+\n");

printf("+-------+\n" );

printf("+-------+\n");

printf("+-------+\n");

return (0);

}

$ ./lines

+-------+

+-------+

+-------+

+-------+

Exercise 8-2 : The total resistance of n resistors in parallel is: 1/R=1/r1 + 1/r2...

Suppose we have a network of two resistors with the values 400 and 200.

Then our equation would be: 1/R=1/200 + 1/400

Substituting in the value of the resistors we get: 1/R = 1/(0.005 + 0.0025) = 1/0.0075 = 133.3...

So the total resistance of our two-resistor network is 133.3.

Write a program to compute the total resistance for any number of parallel resistors.

/*parallel resistors.c - a prog to calculate 2 resistors in parallel
/*that can handle decimal points to 2 places*/
#include <stdio.h>
float R1; /*variable resistor 1 input*/
float R2; /*variable resistor 2 input*/
char line1[10]; /*user input 1 values*/
char line2[10]; /*user input 2 values*/
float result; /*calculation result*/
int main()
{
printf("Enter R1 value: ");
fgets(line1, sizeof(line1), stdin);
sscanf(line1, "%f", &R1 );
printf("Enter R2 value: ");
fgets(line2, sizeof(line2), stdin);
sscanf(line2, "%f", &R2 );
result = 1/((1.0 / R1) + (1.0 / R2));
printf("The result is %0.2f\n", result); /*float answer needs some dec places to account for 1.3 recurring*/
return (0);
}

$ ./resistors
Enter R1 value: 400
Enter R2 value: 200
The result is 133.33

Now it can be amended for function complexity for 2+ inputs...

maybe using the prior calc.c code, as infinite input options are required – and an IFELSE break, with an invalid input warning.

int value;

/*calc.c**/

#include <stdio.h>

char line[100];/* line of data from the input */

int result;

char operator; /* operator the user specified */

int value;

/* the result of the calculations */

/* value specified after the operator */

int main()

{

result = 0; /* initialize the result */

/* Loop forever (or till we hit the break statement) */

while (1)

{

printf("Result: %d\n", result);

printf("Enter “+” and resistor value: ");

fgets(line, sizeof(line), stdin);

sscanf(line, "%c %d", &operator, &value);

if (operator == '+')

{

result += value;

}

else

{

printf("Unknown operator %c\n", operator);

}

}

}

Working Program:

/*parallel resistors.c by steve edwards: calculates summing parallel resistor values

including correct first solo series resistor value. The hardest part of the logic was

placing a mechanism for the running current total for the initial resistor value to

give it's correct series value before the further addition of more in parallel that

then inverts and adds the extra values! */

#include <stdio.h>

char line[100]; /* line of data from the input */

float Rtot; /* running total of all added resistor values */

float value; /*first entered resistor value*/

char operator; /* operator the user specified */

float result; /* inverse running total of all added resistor values */

int main()

{

/* Loop forever (or til we hit the break statement) */

while (1)

{

printf("Enter + and resistor value or q to quit: ");

fgets(line, sizeof(line), stdin);

sscanf(line, "%c %f", &operator, &value);

printf("Resistor value entered: %f\n", value);

printf("Inverse resistor value is: %0.3f\n", 1/value);

if (operator == '+')

{

result = 1.0 / value + Rtot;

Rtot = 1/result;

printf("Total parallel circuit resistance is now: %0.3f\n ", Rtot);

Rtot = 1/Rtot;

}

else

{

printf("Unknown operator %c\n", operator);

}

if (operator == 'q' || operator == 'Q')

{

break;

}

}

return (0);

}

 

parares2.png

Had to stop printfs repeating after quit break with comments.

$ ./parallelresistors
Enter + and resistor value or q to quit: +100
Total parallel circuit resistance is now: 100.00 Ohms
Enter + and resistor value or q to quit: +100
Total parallel circuit resistance is now: 50.00 Ohms
Enter + and resistor value or q to quit: +50
Total parallel circuit resistance is now: 25.00 Ohms
Enter + and resistor value or q to quit: +25
Total parallel circuit resistance is now: 12.50 Ohms
Enter + and resistor value or q to quit: q

Exercise 8-3 : Write a program to average n numbers.

I amended the parallel resistors code to write running total and averages. Interestingly, it shows 2 linear sequences for 1+2+3...with the averages increasing by 0.5 each time.

/*avgnumbers.c amended from parallelres prog*/
#include <stdio.h>
float avg; /*average of all input values*/
int counter; /*number of input loops so number of numbers for avg*/
char line[100]; /* line of data from the input */
float Rtot; /* running total of all added values */
float value; /*entered value*/
char operator; /* operator the user specified */
float result; /* running total of all added values */
int main()
{
/* Loop forever (or til we hit the break statement) */
counter = 0; /*initialise counter*/
Rtot = 0; /*initialise Rtot*/
while (1)
{
printf("Enter + and number value or q to quit: ");
fgets(line, sizeof(line), stdin);
sscanf(line, "%c %f", &operator, &value);
++counter; /*counts loops, so number of user inputs*/
if (operator == '+')
{
Rtot = value + Rtot; /*Rtot is 0 to start*/
printf("Total sum of numbers is now: %0.2f \n", Rtot);
avg = Rtot/counter;
printf("Avg of numbers is now: %0.2f \n", avg);
}
else if (operator == 'q' || operator == 'Q')
break;
else
printf("Unknown operator %c\n", operator);
}
return (0);
}

avgnumbers.png

$ ./avgnumbers
Enter + and number value or q to quit: +1
Total sum of numbers is now: 1.00
Avg of numbers is now: 1.00
Enter + and number value or q to quit: +2
Total sum of numbers is now: 3.00
Avg of numbers is now: 1.50
Enter + and number value or q to quit: +3
Total sum of numbers is now: 6.00
Avg of numbers is now: 2.00
Enter + and number value or q to quit: +4
Total sum of numbers is now: 10.00
Avg of numbers is now: 2.50
Enter + and number value or q to quit: +5
Total sum of numbers is now: 15.00
Avg of numbers is now: 3.00
Enter + and number value or q to quit: +6
Total sum of numbers is now: 21.00
Avg of numbers is now: 3.50
Enter + and number value or q to quit: +7
Total sum of numbers is now: 28.00
Avg of numbers is now: 4.00
Enter + and number value or q to quit: +8
Total sum of numbers is now: 36.00
Avg of numbers is now: 4.50
Enter + and number value or q to quit: +9
Total sum of numbers is now: 45.00
Avg of numbers is now: 5.00
Enter + and number value or q to quit: +10
Total sum of numbers is now: 55.00
Avg of numbers is now: 5.50
Enter + and number value or q to quit: +11
Total sum of numbers is now: 66.00
Avg of numbers is now: 6.00
Enter + and number value or q to quit: q

A simpler program is to edit the total2.c prog to use the loop counter itself, which is quite cool, and use it as the dividend for the total:

total_avg.png

 ./total_avg
Enter Number 1 of 5 1
Enter Number 2 of 5 2
Enter Number 3 of 5 3
Enter Number 4 of 5 4
Enter Number 5 of 5 5
The grand total is 15
The average is 3

./total_avg
Enter Number 1 of 5 2
Enter Number 2 of 5 4
Enter Number 3 of 5 6
Enter Number 4 of 5 8
Enter Number 5 of 5 10
The grand total is 30
The average is 6

Just have to expand it to a while loop that runs until quit so takes up to n numbers..

Exercise 8-4 : Write a program to print out the multiplication table.

/*10 times tables, amended from avgnumbers.c prog*/
#include <stdio.h>
int counter; /*number of input loops so number of numbers for avg*/
char line[100]; /* line of data from the input */
float value; /*entered value*/
float result; /* result of multiplication */
int main()
{
counter = 0; /*initialise counter*/
printf("Enter number to timestable x 10: ");
fgets(line, sizeof(line), stdin);
sscanf(line, "%f", &value);
while (counter <=10) /* Loop 10 times */
{
result = counter * value;
printf("%d X %f is: %0.2f \n", counter, value, result );
++counter; /*counts loops*/
}
return (0);
}

timestables.png

$ ./tables
Enter number to timestable x 10: 1
0 X 1.000000 is: 0.00
1 X 1.000000 is: 1.00
2 X 1.000000 is: 2.00
3 X 1.000000 is: 3.00
4 X 1.000000 is: 4.00
5 X 1.000000 is: 5.00
6 X 1.000000 is: 6.00
7 X 1.000000 is: 7.00
8 X 1.000000 is: 8.00
9 X 1.000000 is: 9.00
10 X 1.000000 is: 10.00
$ ./tables
Enter number to timestable x 10: 1.414213562
0 X 1.414214 is: 0.00
1 X 1.414214 is: 1.41
2 X 1.414214 is: 2.83
3 X 1.414214 is: 4.24
4 X 1.414214 is: 5.66
5 X 1.414214 is: 7.07
6 X 1.414214 is: 8.49
7 X 1.414214 is: 9.90
8 X 1.414214 is: 11.31
9 X 1.414214 is: 12.73
10 X 1.414214 is: 14.14

Exercise 8 -5 : Write a program that reads a character and prints out whether or not it is a vowel or a consonant.

*vowels.c amended from avgnumbers.c prog*/

#include <stdio.h>

char line[100]; /* line of data from the input */

char operator; /* operator the user specified */

int main()

{

/* Loop forever (or til we hit the break statement) */

while (1)

{

printf("Enter a lowercase letter, or ! to quit: ");

fgets(line, sizeof(line), stdin);

sscanf(line, "%c", &operator);

if (operator == '!')

break;

else if (operator == 'a' || operator == 'e' || operator =='i' || operator == 'o' || operator == 'u')

printf("%c is a vowel \n", operator);

else

printf("%c is a consonant or other char \n", operator);

}

return (0);

}

$ ./vowels
Enter a lowercase letter, or ! to quit: a
a is a vowel
Enter a lowercase letter, or ! to quit: e
e is a vowel
Enter a lowercase letter, or ! to quit: i
i is a vowel
Enter a lowercase letter, or ! to quit: o
o is a vowel
Enter a lowercase letter, or ! to quit: u
u is a vowel
Enter a lowercase letter, or ! to quit: q
q is a consonant or other char
Enter a lowercase letter, or ! to quit: 1
1 is a consonant or other char
Enter a lowercase letter, or ! to quit: !

Exercise 8-6: Write a program that converts numbers to words. For example, 895 results in "eight nine five."

Exercise 8-7: The number 85 is pronounced "eighty-five," not "eight five." Modify

the previous program to handle the numbers through 100 so that all numbers come out as we really say them. For example, 13 would be "thirteen" and 100 would be "one hundred."

Exercise 6xx with switch - program to convert metric to Imperial units:

/*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 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;
printf("%0.3f litres is %0.3f pints \n\n", value, result);
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

$ ./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
2
1: convert litres to pints. Enter litre value: 1
1.000 litres is 1.760 pints

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

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

** added extra gallon value to switch 2 - useful for bike tanks!

gallons = result/8;
printf("%0.3f litres is %0.3f pints or %0.3f gallons\n\n", value, result, gallons );

This shows my XJ900 fuel tank off 22 litres about right:

$ ./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
2
1: convert litres to pints. Enter litre value: 22
22.000 litres is 38.715 pints or 4.839 gallons

Jeez! I weigh in at:

3: convert kg to pounds. Enter kg value: 90
90.000 kg is 198.416 pounds in US measures...fat bastard!

Comments are closed.

Post Navigation