C Primer Plus第八章编程练习

第八章编程练习

由于第八章的一些程序涉及到EOF,如果系统没有EOF的话,可以使用其他字符来代替。在这里,我们使用Ctrl+Z来输入EOF字符。

在这里插入图片描述
第二题的完整代码以及运行结果如下:

#include<stdio.h>
void chuLi(int c);
int main(void){
    char ch;
    int i = 0;
    printf("请输入内容:\n");
    while ((ch=getchar())!=EOF)
    {
        i++;
        chuLi(ch);
        if (i%9==0){
            printf("\n");
        }
        
    }
    printf("在文件结尾之前读取到了%d个字符",i);
    getchar();
    return 0;
}
void chuLi(int c){
    if (c < 10){
        printf("^%c:%-5d",c+64,c);
    }else if(c==10){
        printf("\\n:%-5d",c);
    }else if(c==11){
        printf("\\t:%-5d",c);
    }else if(11<c&&c<32){
        printf("^%c:%-5d",c+64,c);
    }else if(32<=c&&c<127){
        printf("%c:%-5d",c,c);
    }else{
        printf("END:%-5d",c,c);
    }

}

在这里插入图片描述

第三题的完整代码以及运行结果如下:

#include<stdio.h>
#include<ctype.h>
int main(void){
    char ch;
    int i = 0,j = 0;
    printf("请输入内容:\n");
    while ((ch=getchar())!=EOF)
    {
        if (islower(ch)){
            i++;
        }else if(isupper(ch)){
            j++;
        }
        
    }
    printf("在文件结尾之前读取到了%d个小写字母,%d个大写字母",i,j);
    getchar();
    return 0;
}

在这里插入图片描述

第四题的完整代码以及运行结果如下:

因为在VSCode运行的时候,要按两次Ctrl+Z,才会识别到EOF,所以在我的运行结果里识别的是六个单词。

#include<stdio.h>
#include<ctype.h>
int main(void){
    char ch;
    int i = 0,j = 0,z = 0;//i为字母计数,j为单词计数,z为开始计数标志
    printf("请输入内容:\n");
    while ((ch=getchar())!=EOF)
    {
        while (ch == '\n'){
            continue;
        }
        if (isalpha(ch)&&z==0){
            i++;
            z = 1;
        }else if(z==1&&isalpha(ch)){
            i++;
        }else if(z==1&&!isalpha(ch)){
            j++;
        }
        
    }
    double x = i/j;
    printf("输入中有%d个字母,有%d个单词,平均每个单词的字母数为:%g\n",i,j,x);
    getchar();
    return 0;
}

在这里插入图片描述

第五题的完整代码以及运行结果如下:

#include<stdio.h>
int main(void){
    int i = 50;
    int min = 0;
    int max = 100;
    printf("想一个1-100中的整数:\n");
    printf("好,下面我将开始猜你想的数\n");
    printf("如果我猜对了,请输入y,如果我猜错了,请输入n");
    printf("你想的数是%d吗?\n",i);
    while (getchar()!='y'){
        while (getchar() != '\n'){
            continue;
        }
        printf("你想的数比%d大吗?(y/n)\n",i);
        if (getchar() == 'y'){
            min = i;
            i = (i + max)/2;
        }else
        {
            max = i;
            i = (i + min)/2;
        }
        while (getchar() != '\n'){
            continue;
        }
        printf("你想的数是%d吗?(y/n)\n",i);     
    }
    printf("我猜中了吧");
    getchar();
    return 0;
}

在这里插入图片描述

关于第六个问题他要求修改章节内的一个函数,我是懒得打一遍,太长了,关于这个函数的修改如下:

在这里插入图片描述

char get_first(void)
{
    int ch;
    while (isspace(ch = getchar()))
        continue;
    return ch;
}

关于第七题,他要我们修改第七章的编程练习8,用字符代替数字选项,这不纯纯找事儿吗

在这里插入图片描述

#include<stdio.h>
#define BASIC1 8.75
#define BASIC2 9.33
#define BASIC3 10.00
#define BASIC4 11.20
#define SHUIONE 0.15
#define SHUITWO 0.20
#define SHUITHREE 0.25
void showMenu(void);//展示工资等级菜单
char getDj(void);//获取工资等级
double jiSuan(double basic);//计算工资等
int main (void){
    float times = 0;//定义实际工作时长 
    char menum;//工资等级
    showMenu();
    printf("请输入您需要设置的工资等级前的代码:\n");
    menum = getDj();
    while (menum!='e')
    {
        switch (menum)
        {
        case 'a':
            jiSuan(BASIC1);
            break;
        case 'b':
            jiSuan(BASIC2);
            break;
        case 'c':
            jiSuan(BASIC3);
            break;
        case 'd':
            jiSuan(BASIC4);
            break;
        }
        showMenu();
        while (getchar() != '\n'){
            continue;
        }
        menum = getDj();
    }
    printf("\nDone!!");
    getchar();
    getchar();
    return 0;
}
void showMenu(void){
    printf("****************************************************************\n");
    printf("Enter the number correspoding to the desired pay rate or action:\n");
    printf("a) $8.75/hr                     b) $9.33/hr\n");
    printf("c) $10.00/hr                    d) $11.20/hr\n");
    printf("e) quit\n");
    printf("****************************************************************\n");
}
char getDj(void){
    int input;
    while (scanf("%c",&input)!=1||input<'a'||input>'e'){
        printf("您输入的值不合法,请重新输入!!\n");
    }
    return input;
}
double jiSuan(double basic){
    float times =0;//定义工作时长
    float num =0;//计算工资时长,加班为1.5倍的时间
    float money = 0;//定义初始工资
    float shui = 0;//定义税金
    float jing = 0;//定义净收入
    printf("请输入您一周工作的小时数,输入小于0或者大于168的值结束\n");
    while (scanf("%f",&times)!=1||times<0||times>168){
        printf("您输入的工作时长不合法,请重新输入:\n");
    }
    /*因为有工资等级的问题,经计算,按照昨天哪一种解法是不完全正确的,因为税金档位问题。所以
    我们统一按照昨天计算第三档的算法
    ,按照300划分,三百以下缴纳第一档税金,超过300,按照第二档缴纳
    超过450的话,第三档在第二档的基础上多缴纳5%的税金,额外再缴纳5%*/
    //计算工作时长,按照40小时划分有无加班时长
    if (times>40){
        num = 40+1.5*(times-40);
    }else{
        num = times;
    }
    money = num*basic;//计算总工资
    //计算税金
    if (money<=300){
        shui = money*SHUIONE;
    }else if (300<money&&money<=450){
        shui = 300*SHUIONE+(money-300)*SHUITWO;
    }else{
        shui = 300*SHUIONE+(money-300)*SHUITWO+(money-450)*(SHUITHREE-SHUITWO);
    }
    //净收入为工资减去税金,这没啥好说的
    jing = money-shui;
    printf("您本周的工资构成为,工资总额:%0.3f,税金:%0.3f,净收入:%0.3f 。\n",money,shui,jing);
}

在这里插入图片描述

最后,我们来看一下第八题
在这里插入图片描述

看上去很长,不过需求并不是很复杂,相当于写一个计算器程序,首先,为了做到和题目格式完全一致,真是费了好大的功夫。首先,介于本人英语不好,只认识add是加法,所以查了一下其他的几个是什么意思,相必大家英语都比我好,所以我就不多说了。我们首先写一个展示选项菜单的函数。

void showMenu(void){
    printf("Enter the operation of your choice:\n");
    printf("a.add              s.subtract\n");
    printf("m.multiply         d.divide\n");
    printf("q.quit\n");
}

这个菜单展示应该都没有什么问题,接下来,按照输出的格式示例,我们要对选项代码进行获取,我们再搞一个函数去做这件事情。

char getCz(void){
    char c;
    while (scanf("%c",&c)!=1||!(c=='a'||c=='s'||c=='m'||c=='d'||c=='q')){
        printf("您输入的选项代码不合法,请重新输入:\n");
    }
    while (getchar() != '\n'){
        continue;
    }
    return c;
}

这部分应该也没有什么问题,获取输入的选项代码,并校验其合法性,然后消耗输入缓存区里的内容,以免对后续操作造成影响。接下来,按照格式,我们要获取第一个值,并加以校验,我们再写一个函数。

float getOne(void){
    char c;
    float one;
    printf("Enter first number: ");
    while (scanf("%f",&one)!=1){
        while ((c=getchar())>32){
            putchar(c);
        }
        printf(" is not an number,\n");
        printf("Please enter a number, sucn as 2.5,-1.78E8,or 3:");
    }
    while (getchar() != '\n'){
        continue;
    }
    return one;
}

这部分呢,因为示例展示了输入不为数字的情况,所以我们按照格式对其进行了实现,也很好理解,数字的话放行,如果输入非数字,去展示并且再次获取输入。同样的,我们再写一个获取第二个值的函数。

float getTwo(char d){
    char c;
    float two;
    printf("Enter second number: ");
    while (scanf("%f",&two)!=1){
        while ((c=getchar())>32){
            putchar(c);
        }
        printf(" is not an number,\n");
        printf("Please enter a number, sucn as 2.5,-1.78E8,or 3:");
    }
    if (d == 'd' && two == 0){
        printf("Enter a number other than 0: ");
        scanf("%f",&two);
    }
    while (getchar() != '\n'){
        continue;
    }
    return two;
}

相较于获取第一个值的函数,这一个函数需要多一个校验,也就是除数不能为0,其余的和上面那个函数基本上没区别。现在获取到两个值,以及需要进行的选项了,那么就剩最后一步,根据不同的选项去计算不同的结果了。我们将上述代码组合起来,在合适的位置进行循环和退出校验,就会得到下面的代码以及运行结果了。

#include<stdio.h>
#include<ctype.h>
void showMenu(void);
char getCz(void);
float getOne(void);
float getTwo(char d);
int main(void){
    char c;
    float a,b;
    showMenu();
    c = getCz();
    while (c !='q')
    {
        a = getOne();
        b = getTwo(c);
        switch (c)
        {
        case 'a':
            printf("%0.2f + %0.2f = %0.2f\n",a,b,(a+b));
            break;
        case 's':
            printf("%0.2f - %0.2f = %0.2f\n",a,b,(a-b));
            break;
        case 'm':
            printf("%0.2f * %0.2f = %0.2f\n",a,b,(a*b));
            break;
        case 'd':
            printf("%0.2f / %0.2f = %0.2f\n",a,b,(a/b));
            break;
        default:
            break;
        }
        showMenu();
        c = getCz();
    }
    printf("Bye.");
    getchar();
    return 0;
}
void showMenu(void){
    printf("Enter the operation of your choice:\n");
    printf("a.add              s.subtract\n");
    printf("m.multiply         d.divide\n");
    printf("q.quit\n");
}
char getCz(void){
    char c;
    while (scanf("%c",&c)!=1||!(c=='a'||c=='s'||c=='m'||c=='d'||c=='q')){
        printf("您输入的选项代码不合法,请重新输入:\n");
    }
    while (getchar() != '\n'){
        continue;
    }
    return c;
}
float getOne(void){
    char c;
    float one;
    printf("Enter first number: ");
    while (scanf("%f",&one)!=1){
        while ((c=getchar())>32){
            putchar(c);
        }
        printf(" is not an number,\n");
        printf("Please enter a number, sucn as 2.5,-1.78E8,or 3:");
    }
    while (getchar() != '\n'){
        continue;
    }
    return one;
}
float getTwo(char d){
    char c;
    float two;
    printf("Enter second number: ");
    while (scanf("%f",&two)!=1){
        while ((c=getchar())>32){
            putchar(c);
        }
        printf(" is not an number,\n");
        printf("Please enter a number, sucn as 2.5,-1.78E8,or 3:");
    }
    if (d == 'd' && two == 0){
        printf("Enter a number other than 0: ");
        scanf("%f",&two);
    }
    while (getchar() != '\n'){
        continue;
    }
    return two;
}

在这里插入图片描述

好,以上就是第八章编程练习的内容,难度适中,将前面讲述的内容与本章的内容进行结合,见得多了也就很好理解了。接下来,就要去完成第九章的编程练习的内容了。

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值