[C language] Programming Exercises (Chapter 7)


Tasks from the seventh chapter of Stephen Prata’s book “C Primer Plus” – “C Control Operators: Branching and Jumps”.

1. Write a program that reads input until a # character is encountered, and then displays the number of spaces read, the number of newlines, and the number of all other characters.

IN THE PROCESS OF WRITING

#include <stdio.h>

int main (void)
{

 char ch;
 int space = 0;
 int newline = 0;
 int all_char = 0;

 printf("Please enter something..\n");

 while ((ch = getchar()) != '#')
  {
    if (ch== ' ')
        space++;
    if (ch== '\n')
        newline++;
    all_char++;
  }

 printf("%d spaces | %d newlines | %d all",
        space, newline, all_char);

getchar();getchar();
return 0;
}

2. Write a program that reads input until the # character is encountered. The program should output each character entered and its ASCII decimal code. Each output line must contain eight character-code pairs.

Hint: Use the character counter and the modulo (%) operation to
output a newline character every eighth iteration of the loop.

#include <stdio.h>

int main (void)
{

 char ch;
 int n=0;

 printf("Please enter something (# to quit)..\n");

 while ((ch = getchar()) != '#')
  {
    if (ch != '\n' && ch != ' ')
    {
        printf("%c-%d ", ch, ch);
        n++;
    }
    if ((n % 8) == 0)
        printf("\n");
  }

getchar();
return 0;
}

3. Write a program that reads integers until the number 0 is encountered. After stopping input, the program should report the total number of even integers entered (excluding 0), the average of even integers entered, the total number of odd integers entered and the mean of odd numbers.

#include <stdio.h>

int main (void)
{

 int i;
 int even = 0;
 int sum_even = 0;
 int odd = 0;
 int sum_odd = 0;
 float average_even, average_odd;

 printf("Enter integer number (0 to quit)..\n");

 while (scanf("%d", &i) == 1 && i !=0 )
 {
    if ( (i%2) == 0 )
        {
            even++;
            sum_even += i;
        }
    else
        {
            odd++;
            sum_odd += i;
        }
 }
 if (even > 0)
    {
    average_even = sum_even/(float)even;
    printf("Even numbers: %d (average %.0f)\n",
        even, average_even);
    }
 if (odd > 0)
    {
    average_odd = sum_odd/(float)odd;
    printf("Odd numbers %d (average %.0f)",
        odd, average_odd);
    }

getchar();getchar();
return 0;
}

4. Using if else statements, write a program that reads input
data until it encounters the # symbol, replaces each dot with an exclamation point
sign, initially present exclamation marks – with two exclamation marks and at the end reports the number of replacements made.

#include <stdio.h>
int main (void)
{

char ch;
int count=0;

printf("Enter something (# to quit)\n");

while ((ch = getchar()) != '#')
{
 if (ch == '.')
    {
    ch = '!';
    count++;
    printf("%c", ch);
    }
 else if (ch == '!')
    {
    putchar('!');
    putchar('!');
    count++;
    }
 else
    printf("%c", ch);
}
printf("There were %d replacements", count);

getchar();getchar();
return 0;
}

5. Do Exercise 4, but with a switch statement.

#include <stdio.h>
int main (void)
{

char ch;
int count=0;

printf("Enter something (# to quit)\n");

while ((ch = getchar()) != '#')
{
    switch (ch)
    {
        case '.':
        {
            count++;
            putchar('!');
            break;
        }
        case '!':
        {
            putchar('!');
            putchar('!');
            count++;
            break;
        }
        default:
            printf("%c", ch);
    }
}
printf("There were %d replacements", count);

getchar();getchar();
return 0;
}

6. Write a program that reads input until it encounters the # character and reports the number of occurrences of the sequence ei.

On a note!
This program should “remember” the previous character as well as the current character. Test it against an input sequence like “Receive your eieio award#”.

#include <stdio.h>
int main (void)
{

char ch;
int e = 0; // flag
int count=0;

printf("Enter something with ei (# to quit)\n");

while ((ch = getchar()) != '#')
{

    if (ch == 'e')
        e = 1;
    else if (ch == 'i' && e == 1)
        {
            count++;
            e = 0;
        }
    else
        e = 0;
}
printf("There were %d ei", count);

getchar();getchar();
return 0;
}
Enter something with ei (# to quit)
Receive your eieio award#
There were 3 ei

7. Write a program that queries the number of hours worked per week and prints out the totals for accruals, taxes, and net pay. Based on the following statements:

but. Basic wage rate = $10.00/hour
b. Overtime hours (exceeding 40 hours per week) = multiplier 1.5
in. Tax rate:
15% from the first $300;
20% off next $150;
25% from the balance.

Use #define constants and don’t worry if the example given
does not comply with current taxation.

The first pancake is lumpy – crookedly considers the tax above 300:

#include <stdio.h>

#define S_PER_H 10 // 10$ per hour
#define OVERWORK 1.5 // x1.5 if more than 40 hours/week

#define TAX_300 15 // 15% for $300
#define ADD_TAX_150 20 // 20% for next $150
#define ADD_TAX_LEFT 25 // 25% from leftover

int main (void)
{

int h = 0; // hours
float total = 0.0;
float tax = 0.0;
float earned = 0.0;

printf("Enter hours/week (q to quit)\n");

while (scanf("%d", &h) == 1)
{

    total = (float)h * S_PER_H;

    if (h > 40)
        total *= OVERWORK;

    tax = (total * TAX_300) / 100;

    if (total > 300.0f)
        tax += (((total-300) * ADD_TAX_150) / 100);
    if (total > 450.0f)
        tax += (((total-450) * ADD_TAX_LEFT) / 100);

    earned = total - tax;

    printf("Total: %.0f (-%.0f$ taxes). Earned: %.0f\n",
          total, tax, earned);
    printf("Enter another value (hours/week) or 'q' to quit\n");
}

getchar();getchar();
return 0;
}

Conclusion (comments added manually):

Enter hours/week (q to quit)
25
Total: 250 (-38$ taxes). Earned: 212 // RIGHT
Enter another value (hours/week) or 'q' to quit
40
Total: 400 (-80$ taxes). Earned: 320 // WRONG
Enter another value (hours/week) or 'q' to quit
80
Total: 1200 (-548$ taxes). Earned: 652 // WRONG
Enter another value (hours/week) or 'q' to quit

Here is a working version:

#include <stdio.h>

#define S_PER_H 10 // 10$ per hour
#define OVERWORK 1.5 // x1.5 if more than 40 hours/week

#define TAX_300 15 // 15% for $300
#define ADD_TAX_150 20 // 20% for next $150
#define ADD_TAX_LEFT 25 // 25% from leftover

int main (void)
{

int h = 0; // hours
float total = 0.0;
float tax = 0.0;
float earned = 0.0;

printf("Enter hours/week (q to quit)\n");

while (scanf("%d", &h) == 1)
{

    total = (float)h * S_PER_H;

    if (h > 40)
        total *= OVERWORK;

    if (total <= 300.0f)
        tax = (total * TAX_300) / 100;

    if (total > 300.0f && total < 450)
    {
        tax = ((300 * TAX_300) / 100);
        tax +=(((total-300) * ADD_TAX_150) / 100);
    }
    if (total >= 450.0f)
    {
        tax = ((300 * TAX_300) / 100);
        tax +=((150 * ADD_TAX_150) / 100);
        tax +=(((total-450) * ADD_TAX_LEFT) / 100);
    }
    earned = total - tax;

    printf("Total: %.0f (-%.0f$ taxes). Earned: %.0f\n",
          total, tax, earned);
    printf("Enter another value (hours/week) or 'q' to quit\n");
}

getchar();getchar();
return 0;
}
Enter hours/week (q to quit)
25
Total: 250 (-38$ taxes). Earned: 212
Enter another value (hours/week) or 'q' to quit
40
Total: 400 (-65$ taxes). Earned: 335
Enter another value (hours/week) or 'q' to quit
80
Total: 1200 (-262$ taxes). Earned: 938
Enter another value (hours/week) or 'q' to quit

The program looks somewhat cumbersome, but very understandable. Now let’s bring it to a more universal form (this will be useful for the next task):

#include <stdio.h>

#define RATE_1 10 // 10$ per hour

#define OVERTIME 40 // >40 hours is overtime
#define OVERWORK 1.5 // x1.5 if overtime

#define BRACKET_1 300.0f
#define TAX_1 0.15 // 15% for $300

#define BRACKET_2 150.0f
#define TAX_2 0.2 // 20% for next $150

#define TAX_3 0.25 // 25% from leftover

int main (void)
{

int h = 0; // hours
float total = 0.0;
float tax = 0.0;
float earned = 0.0;

printf("Enter hours/week (q to quit)\n");

while (scanf("%d", &h) == 1)
{

    total = (float)h * RATE_1;

    if (h > OVERTIME)
        total *= OVERWORK;

    if (total <= BRACKET_1)
        tax = total * TAX_1;

    if (total > BRACKET_1 && total < BRACKET_1 + BRACKET_2)
    {
        tax = BRACKET_1 * TAX_1;
        tax +=((total - BRACKET_1) * TAX_2);
    }
    if (total >= BRACKET_1 + BRACKET_2)
    {
        tax = BRACKET_1 * TAX_1;
        tax +=(BRACKET_2 * TAX_2);
        tax +=((total - (BRACKET_1+BRACKET_2)) * TAX_3);
    }
    earned = total - tax;

    printf("Total: %.0f (-%.0f$ taxes). Earned: %.0f\n",
    total, tax, earned);
    printf("Enter another value (hours/week) or 'q' to quit\n");
}

getchar();getchar();
return 0;
}

8. Modify assumption a) in exercise 7 so that the program provides a menu with tariff rates. To select a tariff rate, use the switch statement. After running the program, the output should be similar to the one below:

Введите число, соответствующее желаемой тарифной ставке или действию:
1) $8.75/ч            2) $9.33/ч
3) $10.00/ч           4) $11.20/ч
5) Выход

If option 1 to 4 is selected, the program should ask for the number of hours worked. The program should repeat until option 5 is selected. When entering something other than options 1-5, the program should remind the user of valid options for input and wait for input again. For different tariff and tax rates, use #define constants.

#include <stdio.h>

#define RATE_1 8.75 // $ per hour
#define RATE_2 9.33
#define RATE_3 10.00
#define RATE_4 11.20

#define OVERTIME 40 // >40 hours is overtime
#define OVERWORK 1.5 // x1.5 if overtime

#define BRACKET_1 300.0f
#define TAX_1 0.15 // 15% for $300

#define BRACKET_2 150.0f
#define TAX_2 0.2 // 20% for next $150

#define TAX_3 0.25 // 25% from leftover

int main (void)
{

int h = 0; // hours
int r; // rate option
float rate = 0.0; // choosen rate
float total = 0.0;
float tax = 0.0;
float earned = 0.0;

printf("Choose your pay rate:\n");
printf("1) $8.75/hr     2) $9.33/hr\n");
printf("3) $10.00/hr    4) $11.20/hr\n");
printf("5) quit\n");

scanf("%d", &r);

while (((int)r) > 5 || ((int)r) < 1)
{
    while (getchar() != '\n') // clearing buffer after letter
        continue;
    printf("Please choose your pay rate:\n");
    printf("1) $8.75/hr     2) $9.33/hr\n");
    printf("3) $10.00/hr    4) $11.20/hr\n");
    printf("5) quit\n");
    scanf("%d", &r);
}

switch (r)
{
    case 1:
        rate = RATE_1;
        break;
    case 2:
        rate = RATE_2;
        break;
    case 3:
        rate = RATE_3;
        break;
    case 4:
        rate = RATE_4;
        break;
    case 5:
        goto end;
    }

printf("Enter hours/week (q to quit)\n");

while (scanf("%d", &h) == 1)
{

    total = (float)h * rate;

    if (h > OVERTIME)
        total *= OVERWORK;

    if (total <= BRACKET_1)
        tax = total * TAX_1;

    if (total > BRACKET_1 && total < BRACKET_1 + BRACKET_2)
    {
        tax = BRACKET_1 * TAX_1;
        tax +=((total - BRACKET_1) * TAX_2);
    }
    if (total >= BRACKET_1 + BRACKET_2)
    {
        tax = BRACKET_1 * TAX_1;
        tax +=(BRACKET_2 * TAX_2);
        tax +=((total - (BRACKET_1+BRACKET_2)) * TAX_3);
    }
    earned = total - tax;

    printf("Total: %.0f (-%.0f$ taxes). Earned: %.0f\n",
            total, tax, earned);
    printf("Enter another value (hours/week) or 'q' to quit\n");
}

end:
printf("See you next time!");

getchar();getchar();
return 0;
}

This program was very cool to write. In the process, I came across the problem of jamming (jam) when entering any character instead of 1-5; about this separate article.

9. Write a program that takes a positive integer as input and displays all prime numbers that are less than or equal to the input number.

#include <stdio.h>

int main (void)
{

int n, i;
int f; // flag prime

printf("Enter positive integer number or q to exit\n");

for (scanf ("%d", &n) == 1; n>1; n--)
{
    for (i=n-1, f = 0; n > 1 && i > 1; i--)
    {
        if (n % i == 0)
            f = 1;
    }
    if (f != 1)
        printf("%d ", n);
}

getchar(); getchar();
return 0;
}

10. In 1988, the United States federal tax rate scale was the simplest ever. It contained four categories, each of which included two rates. Below are the most common figures (dollar amounts represent taxable income).

Category Tax
lonely 15% off the first $17,850 plus 28% on any amount above that
Head of the family 15% on the first $23,900 plus 28% on the amount above
Married, joint
housekeeping
15% off the first $29,750 plus 28% on any amount above that
Married, separated
housekeeping
15% off the first $14,875 plus 28% on the amount above

For example, a lone worker earning taxable income in
$20,000, pays taxes of 0.15 x $17,850 + 0.28 x ($20 $17,850). Write
program that allows the user to specify the category and taxable
taxable income, and then calculates the tax amount. Use a loop to
the user could enter different taxation options.

The first option turned out to be crooked; in addition, no global loop is used:

#include <stdio.h>

int main (void)
{

int c; // category
int category; // choosen category
int gross; // gross income
const int b1 = 17850;  // b.. is bracket $
const int b2 = 23900;
const int b3 = 29750;
const int b4 = 14875;
const float rate_1 = 0.15f;
const float rate_2 = 0.28f;
float tax; // tax
float net; // net income

printf("Choose your tax category:\n");

printf("1) Single: \
(15%% of first $17,850 plus 28%% of excess\n");
printf("2) Head of Household: \
15%% of first $23,900 plus 28%% of excess\n");
printf("3) Married, Joint: \
15%% of first $29,750 plus 28%% of excess\n");
printf("4) Married, Separate: \
15%% of first $14,875 plus 28%% of excess\n");
printf("5) Quit\n");

scanf("%d", &c);

while (!(c < 5) && !(c > 0))
{   while (getchar() != '\n')
        ;                     // ; flush buffer
    scanf("%d", &c);
}
switch(c)
{
    case 1:
    { category = 1;
        break; }
    case 2:
    { category = 2;
        break; }
    case 3:
    { category = 3;
        break; }
    case 4:
    { category = 4;
        break; }
    case 5:
        goto end;
}

printf("Enter your gross income:\n");

while (scanf("%d", &gross) == 1)
{
    if (category == 1)
        if (gross <= b1)
            tax = gross * rate_1;
        else
            tax = (b1 * rate_1) + ((gross - b1)*rate_2);
    if (category == 2)
        if (gross <= b2)
            tax = gross * rate_1;
        else
            tax = (b2 * rate_1) + ((gross - b2)*rate_2);
    if (category == 3)
        if (gross <= b3)
            tax = gross * rate_1;
        else
            tax = (b3 * rate_1) + ((gross - b3)*rate_2);
    if (category == 4)
        if (gross <= b4)
            tax = gross * rate_1;
        else
            tax = (b4 * rate_1) + ((gross - b4)*rate_2);

    net = gross - tax;

    printf("Gross: %d; tax: %.0f; net: %.0f\n",
            gross, tax, net);
    printf("Enter another income of 'q' to quit:\n");
}

end: printf("Bye!");    // goto category 5 choice to quit

getchar(); getchar();

return 0;
}

The second option (the indents moved out decl):

#include <stdio.h>

int main (void)
{

int category; // category
int bracket; // choosen category
int gross; // gross income
const int b1 = 17850;  // b.. is bracket $
const int b2 = 23900;
const int b3 = 29750;
const int b4 = 14875;
const float rate_1 = 0.15f;
const float rate_2 = 0.28f;
float tax;
float net; // net income
int flag; // "continue MAIN LOOP?" flag

do { // MAIN LOOP start

printf("Choose your tax category:\n");

printf("1) Single: \
(15%% of first $17,850 plus 28%% of excess\n");
printf("2) Head of Household: \
15%% of first $23,900 plus 28%% of excess\n");
printf("3) Married, Joint: \
15%% of first $29,750 plus 28%% of excess\n");
printf("4) Married, Separate: \
15%% of first $14,875 plus 28%% of excess\n");
printf("5) Quit\n");

scanf("%d", &category);

while (!(category < 5) && !(category > 0))
{   while (getchar() != '\n')
        ;                     // ; flush buffer
    scanf("%d", &category);
}
switch(category)
{
    case 1:
    { bracket = b1;
        break; }
    case 2:
    { bracket = b2;
        break; }
    case 3:
    { bracket = b3;
        break; }
    case 4:
    { bracket = b4;
        break; }
    case 5:
        goto end;
}

printf("Enter your gross income:\n");

while (scanf("%d", &gross) != 1)
    while (getchar() != '\n')  // flush buffer
	    continue;
if (gross <= bracket)
    tax = gross * rate_1;
else
tax = (bracket * rate_1) + ((gross - bracket)*rate_2);

net = gross - tax;

printf("Gross: %d; tax: %.0f; net: %.0f\n",
       gross, tax, net);
while (getchar() != '\n')  // flush buffer
	continue;

printf("Make another calculation (y) or any key to quit\n");

if (getchar() == 'y')
    flag = 1;

} while (flag == 1);  // MAIN LOOP end

end: printf("Bye!");

getchar(); getchar();

return 0;
}

11. ABC Mail Order Grocery sells artichokes for $2.05/lb, beets for $1.15/lb, and carrots for $1.09/lb. Before shipping costs are added, the company provides a 5% discount on orders of $100 or more. Costs are $6.50 for shipping and handling on orders 5 pounds or less, $14.00 for handling and shipping on orders between 5 pounds and 20 pounds, and $14.00 plus $0.50 per pound for shipping orders over 20 pounds. Write a program that uses the switch statement in a loop so that, in response to input, the user is given the option of specifying the desired weight of the artichokes in pounds; in response to input b is the weight of the beets in pounds; in response to input c – weight of carrots in pounds; and in response to the input q – complete the order process. The program should keep records of amounts on an accrual basis. That is, if the user enters 4 pounds of beets and later enters another 5 pounds of beets, the program should report an order of 9 pounds of beets. The program should then calculate the total cost, the discount if any, the shipping costs, and the total order amount. Next, the program should display all the information about the purchase: the cost per pound of the product, the number of pounds ordered, the cost of each type of vegetable ordered, the total cost of the order, the discount (if any), the shipping costs, and the total amount of the order, including all costs.

Marvelous. In this program, for the first time, I encountered the fact that I misunderstood the “customer” (the condition of the problem). As a result, I had to redo everything a couple of times – at first I used the numbers 123, instead of abc (respectively, I checked all the curves), then I got a glitch and I hung the exit from the program (and not from the order!), For some reason, I had in my head just such a (not according to TK) condition of the problem. In general, once again I got hit on the head for laziness – it is necessary to clearly prescribe the algorithm of the program on a piece of paper – in strict accordance with the TOR. Otherwise, you will be tormented to redo it later … Well .. It is hard in learning, easy in battle;)

Also, I specifically write this and the previous two programs through different loops (loops .. cycles) in order to practice. So the code is:

#include <stdio.h>

#define ARTICHOKE  2.05 // $ price per lb
#define BEET       1.15 // $ price per lb
#define CARROT     1.09 // $ price per lb
#define DISCOUNT   0.95  // % for >= 100$
#define SHIPPING_1 6.5  // $ for 5-20 pounds (lb)
#define SHIPPING_2 0.5  // $ per pound for 20+ pounds

void flush_buffer (void);

int main (void)
{

char menu;        // menu options abcq
float product;   // product choice menu
float weight;
float artichoke = 0.0; // weight
float beet = 0.0;
float carrot = 0.0;
float artichoke_price;
float beet_price;
float carrot_price;
float total;  // $ for order without delivery
float sum_weight;
float delivery = 0.0;
float pay;    // price for everything

 printf("Which vegetable you wish to buy?\n");
 printf("a) Artichoke 2.05$\nb) Beet 1.15$\nc) Carrot 1.09$\
 \nq) Finish order\n");

while ((menu = getchar ()) != 'q')
{
 if (menu == '\n')  // to flush space after abc were
    continue;       // choosen (so 'q' will work)

 if (menu != 'a' && menu != 'b' && menu != 'c' && menu != 'q')
    flush_buffer();

 switch (menu)
 {
    case 'a':
      { printf("How much pounds?\n");
        if (scanf("%f", &weight) != 1 || weight < 0)
            flush_buffer();
        artichoke += weight;
        break; }
    case 'b':
      { printf("How much pounds?\n");
        if (scanf("%f", &weight) != 1 || weight < 0)
            flush_buffer();
        beet += weight;
        break; }
    case 'c':
      { printf("How much pounds?\n");
        if (scanf("%f", &weight) != 1 || weight < 0)
            flush_buffer();
        carrot += weight;
        break; }
 }  // switch

 printf("Which vegetable you wish to buy?\n");
 printf("a) Artichoke 2.05$\nb) Beet 1.15$\nc) Carrot 1.09$\
 \nq) Finish order\n");

}  // while

artichoke_price = artichoke*ARTICHOKE;
beet_price = beet*BEET;
carrot_price = carrot*CARROT;

total = artichoke_price + beet_price + carrot_price;

if (total >= 100.0) // discount
    total *= DISCOUNT;

sum_weight = artichoke + beet + carrot;

if (sum_weight <= 5.0 && sum_weight > 0.0)
    delivery = 6.5;
if (sum_weight > 5.0 && sum_weight <= 20.0)
    delivery = 14.0;
if (sum_weight > 20.0)
    delivery = 14.0 + ((sum_weight - 20.0)*0.5);

pay = total + delivery;

printf("You've ordered:\n");

if (artichoke != 0.0)
    printf("%.1f lb artichoke for %.1f$ (%.2f$ per 1 lb)\n",
    artichoke, artichoke_price, ARTICHOKE);
if (beet != 0.0)
    printf("%.1f lb beet for %.1f$ (%.2f$ per 1 lb)\n",
    beet, beet_price, BEET);
if (carrot != 0.0)
    printf("%.1f lb carrot for %.1f$ (%.2f$ per 1 lb)\n",
    carrot, carrot_price, CARROT);

printf("Cost of vegetables: %.1f$ ", total);
if (total >= 100.0) // note about discount
    printf ("(with discount 5%)");
printf("\n");
if (delivery != 0.0)
printf("Delivery will cost: %.1f$\n", delivery);
printf("Total order cost: %.1f$ ", pay);

getchar(); getchar();

return 0;

}  // main

void flush_buffer (void)
{
    while (getchar () != '\n')
        return;
}

In general, this last program was very difficult. There are many subtleties associated with the correct exit from the loop. Since the author of the book wrote that it is better not to use goto (except for error output and other emergency cases), I tried not to resort to it, which led to some difficulties. But in the end, everything works! %)

I will be glad to your comments!


This entry was posted in C language (en). Bookmark the permalink.

Leave a Reply

🇬🇧 Attention! Comments with URLs/email are not allowed.
🇷🇺 Комментарии со ссылками/email удаляются автоматически.