Jimmy Chen

A Programmer

C Primer Plus 第六版 第八章课后编程练习答案

编程环境Visual Studio 2017

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>


// practice 1
void p8_1(void)
{
    char ch = 0;
    int n_char = 0;
    while ((ch = getchar()) != EOF)
    {
        n_char++;
    }

    printf("There are %d characters in the file!\n", n_char);

    return;
}


// practice 2
void p8_2(void)
{
    char ch = 0;
    int n_char = 0;
    while ((ch = getchar()) != EOF)
    {
        n_char++;
        if (ch < ' ')
        {
            if ('\t' == ch)
            {
                putchar('\\');
                putchar('t');
                printf(":%d ", ch);
            }
            else if ('\n' == ch)
            {
                putchar('\\');
                putchar('n');
                printf(":%d ", ch);
            }
            else
            {
                putchar('^');
                putchar(ch+64);
                printf(":%d ", ch);
            }
        }
        else
        {
            putchar(ch);
            printf(":%d ", ch);
        }
        if (n_char % 10 == 0)
        {
            printf("\n");
        }

    }
}


// practice 3
void p8_3(void)
{
    char ch = 0;
    int n_upper = 0;
    int n_lower = 0;

    while ((ch = getchar()) != EOF)
    {
        if (islower(ch))
        {
            n_lower++;
        }
        else if (isupper(ch))
        {
            n_upper++;
        }
    }

    printf("There are %d upper character and %d lower charecter.\n", n_upper, n_lower);

    return; 
}


// practice 4
void p8_4(void)
{
    char ch = 0;
    char ch_pre = 0;
    int n_word = 0;
    int total_chr = 0;
    int word_chr = 0;
    double word_chr_avg = 0;

    while (ch = getchar()) // 清除文件开头处的空格、标点和换行符等
    {
        if (isalpha(ch))
        {
            break;
        }
    }

    while (ch != EOF)
    {
        if ((' ' == ch || '\n' == ch) && !isspace(ch_pre)) // 排除连续空格情况
        {
            n_word++;
            printf("ch_pre = %c\n", ch_pre);
            total_chr += word_chr;
            printf("word_chr = %d, total_chr = %d\n", word_chr, total_chr);
            word_chr = 0;
        }
        else if (isspace(ch))  // 清除连续的空格
        {
            ch_pre = ch;
            ch = getchar();
            continue;
        }
        if (!ispunct(ch) && !isspace(ch))
        {
            word_chr++;
        }
        ch_pre = ch;
        ch = getchar();
    }

    if (!isspace(ch_pre))
    {
        n_word++;
        printf("ch_pre = %c\n", ch_pre);
        total_chr += word_chr;
    }

    word_chr_avg = (double)total_chr / n_word;

    printf("Total words: %d, Total characters: %d, Characters per word: %.2lf", n_word, total_chr, word_chr_avg);
}


// practice 5
void p8_5(void)
{
    char ch = 0;
    int upper = 100;
    int lower = 0;
    int guest = 50;

    printf("I guest the number is 50. Is it right(Y/N)?");
    scanf_s("%c", &ch);
    getchar();

    while ('Y' != ch)
    {
        printf("Ok, the number you chosen is bigger or smaller than I guest?(B/S)");
        scanf_s("%c", &ch);
        getchar();
        if ('B' == ch)
        {
            lower = guest;
            guest = (lower + upper) / 2;
        }
        else
        {
            upper = guest;
            guest = (lower + upper) / 2;
        }

        printf("I guest the number is %d, Is it right(Y/N)?", guest);
        scanf_s("%c", &ch);
        getchar();
    }

    printf("HAHA, I win!");

    return;
}


// practice 6
char get_first(void)
{
    int ch = 0;

    while (!isalpha(ch = getchar()))
    {
        continue;
    }

    return ch;
}
void p8_6(void)
{
    char ch = get_first();

    putchar(ch);
}


// practice 7
#define RATE1 0.15
#define RATE2 0.20
#define RATE3 0.25
void p8_7(void)
{
    char chooice = 0;

    double work_hours = 0;
    double total_income = 0;
    double tax = 0;
    double net_income = 0;
    double hourly_wage = 0;

    while (1)
    {
        printf("Enter the number corresponding to the desired pay rate to action:\n");
        printf("%-20s%-20s\n%-20s%-20s\n%-20s\n", "a) $8.75/hr", "b) $9.33/hr", "c) $10.00/hr", "d) $11.20/hr", "q) quit");
        scanf_s("%c", &chooice);
        getchar();

        switch (chooice)
        {
        case 'a':
            hourly_wage = 8.75;
            break;

        case 'b':
            hourly_wage = 9.33;
            break;

        case 'c':
            hourly_wage = 10.00;
            break;

        case 'd':
            hourly_wage = 11.20;
            break;

        case 'q':
            return;

        default:
            printf("Please enter the choice between a to d and q\n");
            continue;
        }


        printf("How long have you worked:");
        scanf_s("%lf", &work_hours);
        getchar();
        if (work_hours > 40)
        {
            work_hours = (work_hours - 40) * 1.5 + 40;
        }

        total_income = work_hours * hourly_wage;
        if (total_income <= 300)
        {
            tax = total_income * RATE1;
            net_income = total_income - tax;
        }
        else if (300 < total_income <= 450)
        {
            tax = 300 * RATE1 + (total_income - 300) * RATE2;
            net_income = total_income - tax;
        }
        else
        {
            tax = 300 * RATE1 + 150 * RATE2 + (total_income - 450) * RATE3;
            net_income = total_income - tax;
        }

        printf("total income = %.2lf, tax = %.2lf, net income = %.2lf\n", total_income, tax, net_income);
    }


    return;
}


// practice 8
// 浮点数无法和0.0进行"=="判断,设置一个判断阀值
#define ABS_VAL 0.000001
void p8_8(void)
{
    float number1 = 0.0;
    float number2 = 0.0;
    char choice = 0;

    do
    {
        printf("Enter the operation of your choice:\n");
        printf("%-20s%-20s\n%-20s%-20s\n%-20s\n", "a. add", "s. subtract", "m. multuply", "d. divide", "q. quit");
        // 如果scanf的返回值为1并且输入值是a、s、m、d、q中之一代表输入成功,这里取反剔除不符合条件的输入
        if (!(scanf("%c", &choice) == 1 && (('a' == choice) || ('s' == choice) || ('m' == choice) || ('d' == choice) || ('q' == choice))))
        {
            printf("Please enter the correct operation, please enter again!\n");
            while (getchar() != '\n')
            {
                continue;
            }
            continue;
        }
        getchar();

        if ('q' == choice)
        {
            printf("Bye!\n");
            return;
        }

        printf("Enter first number:");
        while (scanf_s("%f", &number1) != 1)
        {
            char ch = 0;
            while ((ch = getchar()) != '\n')
            {
                putchar(ch);
            }
            printf(" is not an number.\n");
            printf("Please enter a number, such as 2.5, -1.78E8, or 3: ");
        }
        getchar();

        printf("Enter second number:");
        while (scanf_s("%f", &number2) != 1)
        {
            char ch = 0;
            while ((ch = getchar()) != '\n')
            {
                putchar(ch);
            }
            printf(" is not an number.\n");
            printf("Please enter a number, such as 2.5, -1.78E8, or 3: ");
        }
        getchar();

        switch (choice)
        {
        case 'a':
            printf("%f + %f = %f\n", number1, number2, (number1 + number2));
            break;

        case 's':
            printf("%f - %f = %f\n", number1, number2, (number1 - number2));
            break;

        case 'm':
            printf("%f * %f = %f\n", number1, number2, (number1 * number2));
            break;

        case 'd':
            //在阈值区间内,将输入值判断为零,要求重新输入
            while (number2 > -ABS_VAL && number2 < ABS_VAL)
            {
                printf("Enter a number other than 0:");
                while (scanf_s("%f", &number2) != 1)
                {
                    char ch = 0;
                    while ((ch = getchar()) != '\n')
                    {
                        putchar(ch);
                    }
                    printf(" is not an number.\n");
                    printf("Please enter a number, such as 2.5, -1.78E8, or 3: ");
                }
                getchar();
            }
            printf("%f / %f = %f\n", number1, number2, (number1 / number2));
            break;

        default:
            break;
        }
    } while (1);

    return;
}

int main(int argc, char **argv)
{
    p8_8();

    while (getchar());

    return 0;
}

此文为博主原创文章,转载请注明出处

  1. Ninw说道:

    第八题
    开始输出选项以外的字符,都能进入下一条语句。

    1. jimmychen说道:

      Thanks!有个逻辑判断没写对,已经改好了

  2. ch说道:

    楼主第4题的ch_pre是什么意思

    1. jimmychen说道:

      记录前一个字符内容,用来判断连续空格使用的

  3. Nossier Ped说道:

    楼主你好,我现在也在做第八章的习题,关于第2题,我和您答案基本相同,但是题目中说“每次遇到换行符打印新的一行”,我理解的意思是程序允许输入多行,而不是在按下回车后就显示结果,应该是在按下Ctrl+D后才显示结果,所以感觉咱们的答案都不符合题意,但我水平有限,不知如何改正,望能得到您的答复,若我有表述不清的地方,还请您和我一同讨论,感谢您的博客,对我学习这本书有很大帮助。

    1. jimmychen说道:

      因为书不在身边,所以具体意思我这边暂时看不了了,那就先按照你的意思来理解。如果要做到按下Ctrl-D后才显示的话,一方面控制台要通过系统函数来直接获取到键盘的输入值,否则输入值都是会缓存在输入缓冲区的;其次就是通过char数组将所有的输入值缓存起来了,下面是我按照这个要求写的程序,与你交流:

      // practice 2
      void print_ch(char ch)
      {
      	if (ch < ' ')
      	{
      		if ('\t' == ch)
      		{
      			putchar('\\');
      			putchar('t');
      		}
      		// 直接按回车键的ASCII键值
      		else if ('\r' == ch)
      		{
      			putchar('\\');
      			putchar('r');
      		}
      		// Ctrl-Enter的ASCII键值
      		else if ('\n' == ch)
      		{
      			putchar('\\');
      			putchar('n');
      		}
      		else
      		{
      			putchar('^');
      			putchar(ch + 64);
      		}
      	}
      	else
      	{
      		putchar(ch);
      	}
      }
      void p8_2(void)
      {
      	char ch = 0;
      	char input[1024] = { 0 };
      	int n_char = 0;
      	// _getch()能够直接获取键盘输入的键值
      	while ((ch = _getch()) != EOF)
      	{
      		// Ctrl-D的ASCII键值为4
      		if (4 == ch) {
      			printf("\n");
      			for (int i = 0; i < n_char; i++) {
      				print_ch(input[i]);
      				printf(":%d ", input[i]);
      				if (i % 10 == 9)
      					printf("\n");
      			}
      		}
      		else {
      			input[n_char] = ch;
      			n_char++;
      			print_ch(ch);
      		}
      	}
      }
      

发表评论

电子邮件地址不会被公开。 必填项已用*标注

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d 博主赞过: