第八章编程练习
由于第八章的一些程序涉及到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",×)!=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;
}
好,以上就是第八章编程练习的内容,难度适中,将前面讲述的内容与本章的内容进行结合,见得多了也就很好理解了。接下来,就要去完成第九章的编程练习的内容了。