C primer plus课后习题 第八章

1.设计一个程序, 统计在读到文件结尾之前读取的字符数。
#include <stdio.h>
int main(void)
{ char c ;
int i=0 ;
while((c=getchar())!=EOF)
i++ ;

printf("Total characters :%d",i ) ;

}

2.编写一个程序, 在遇到 EOF 之前, 把输入作为字符流读取。 程序要打印每个输入的字符及其相应的ASCII十进制值。
注意, 在ASCII序列中,空格字符前面的字符都是非打印字符, 要特殊处理这些字符。 如果非打印字符是换行符或制表符, 则分别打印\n或\t。
否则, 使用控制字符表示法。 例如, ASCII的1是Ctrl+A, 可显示为^A。 注意, A的ASCII值是Ctrl+A的值加上64。 其他非打印字符也有类似的关系。
除每次遇到换行符打印新的一行之外, 每行打印10对值。 (注意: 不同的操作系统其控制字符可能不同。 )
//2.编写一个程序, 在遇到 EOF 之前, 把输入作为字符流读取。 程序要打印每个输入的字符及其相应的ASCII十进制值。
//注意, 在ASCII序列中,空格字符前面的字符都是非打印字符, 要特殊处理这些字符。 如果非打印字符是换行符或制表符, 则分别打印\n或\t。
//否则, 使用控制字符表示法。 例如, ASCII的1是Ctrl+A, 可显示为^A。 注意, A的ASCII值是Ctrl+A的值加上64。 其他非打印字符也有类似的关系。
//除每次遇到换行符打印新的一行之外, 每行打印10对值。 (注意: 不同的操作系统其控制字符可能不同。 )

#include <stdio.h>
int main(void)
{ int ch,i=0 ;
while((ch=getchar())!=EOF)
{
if (ch<’ ‘)
{
switch (ch)
{
case ‘\t’:
printf("\t-%d “,ch) ;
break ;
case ‘\n’:
printf(”\n-%d “,ch) ;
break ;
default :
printf(”^%c-%d “,ch+64,ch) ;
break ;
}
}
else
{
printf(”%c-%d ",ch,ch) ;
}
if(i++>0 && i%10==0)
putchar(’\n’) ;

}

}

3.编写一个程序, 在遇到 EOF 之前, 把输入作为字符流读取。 该程序
要报告输入中的大写字母和小写字母的个数。 假设大小写字母数值是连续
的。 或者使用ctype.h库中合适的分类函数更方便。
#include <stdio.h>
#include <ctype.h>
int main(void)
{
int ch ,upper=0,lower=0;
while ((ch=getchar())!=EOF)
{
if(isupper(ch))
upper++ ;
if(islower(ch))
lower++ ;
}
printf(“Upper:%d,Lower:%d .\n”,upper,lower) ;
}

4.编写一个程序, 在遇到EOF之前, 把输入作为字符流读取。 该程序要
报告平均每个单词的字母数。 不要把空白统计为单词的字母。 实际上, 标点
符号也不应该统计, 但是现在暂时不同考虑这么多(如果你比较在意这点,
考虑使用ctype.h系列中的ispunct()函数) 。
#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>
int main(void)
{
int ch,n_chars=0,n_words=0;
bool inword = false ;

while ((ch=getchar())!=EOF)
{	
	//非空格,非标点符号,记为一个单词的开始 
	if(!isspace(ch) && !ispunct(ch) && !inword)
	{
		inword=true ;
		n_words++ ;
	}	
	
	//空格或者标点,结束一个单词 
	if((isspace(ch) || ispunct(ch))&& inword)
	{
		inword=false ; 
	}
	
	//如果是单词,就增加字母数 
	if(inword)
		n_chars++ ;
	 
}
printf("Total words: %d ,total chars of words :%d \n",n_words,n_chars) ;
printf("avg chars of words: %.2f \n",(float)n_chars/n_words) ;

}

5.修改程序清单8.4的猜数字程序, 使用更智能的猜测策略。 例如, 程序
最初猜50, 询问用户是猜大了、 猜小了还是猜对了。 如果猜小了, 那么下一
次猜测的值应是50和100中值, 也就是75。 如果这次猜大了, 那么下一次猜
测的值应是50和75的中值, 等等。 使用二分查找(binary search) 策略, 如
果用户没有欺骗程序, 那么程序很快就会猜到正确的答案。
#include <stdio.h>
int main(void)
{
int response,guess=50 ;
int high=100,low=1 ;
printf(“Pick an integer from 1 to 100. I will try to guess “);
printf(“it.\nRespond with a y if my guess is right and with”);
printf(”\nan b or s if it is bigger or smaller than your number.\n”);
printf(“Uh…is your number %d?\n”, guess);
while ((response = getchar()) != ‘y’) /* 获取响应 */
{

	if (response =='b')
	{
		high=guess ;
		guess=(high+low)/2 ;
		printf("Well, then, is it %d?\n", guess);
	}	
	else if(response == 's')
	{	low=guess ;
		guess=(high+low)/2 ;
		printf("Well, then, is it %d?\n", guess);
	}	
	else
		printf("Sorry, I understand only b or s.\n");
		
	while (getchar() != '\n')
		continue; /* 跳过剩余的输入行 */ 
}
printf("I knew I could do it!\n");
return 0;

}

6.修改程序清单8.8中的get_first()函数, 让该函数返回读取的第1个非空白字符, 并在一个简单的程序中测试。
#include <stdio.h>
char get_first(void);
int main(void)
{
printf("%c",get_first()) ;
return 0;
}
char get_first(void)
{
int ch;
scanf(" %c",&ch);
while (getchar() != ‘\n’)
continue;
return ch;
}

7.修改第7章的编程练习8, 用字符代替数字标记菜单的选项。 用q代替5
作为结束输入的标记。
#include <stdio.h>
#define WORK_HOURS_PER_WEEK 40
#define ORVERTIME 1.5
#define TAXRATE1 0.15
#define TAXRATE2 0.20
#define TAXRATE3 0.25
#define TAXBREAK1 300
#define TAXBREAK2 150
char get_first(void) ;
char get_choice(void) ;
int main (){
float total_salary=0,taxation=0,net_income=0;
float work_hours ;
int choice ;
int flag=1 ;
float SALARY_PER_HOUR ;

while((choice=get_choice())!='q'){  
	switch (choice)
	{
        case 'a':
            SALARY_PER_HOUR=8.75 ;
            break ;
        case 'b':
            SALARY_PER_HOUR=9.33 ;
            break ;
        case 'c':
            SALARY_PER_HOUR=10.00 ;
            break ;
        case 'd':
            SALARY_PER_HOUR=11.20 ;
            break ;
        default:
            printf("Program error!") ;
            flag=0 ;
            break ; 
    } 
    
    if (!flag)
    	break ;

    printf("\nPlease enter the working hours of this week :");
    if(scanf("%f",&work_hours)==1 && work_hours >0){

        //计算总收入
        if(work_hours>WORK_HOURS_PER_WEEK){
            total_salary=((work_hours-WORK_HOURS_PER_WEEK)*ORVERTIME
                    +WORK_HOURS_PER_WEEK)*SALARY_PER_HOUR ;//加班时间按1.5倍计算
        } else{
            total_salary=work_hours*SALARY_PER_HOUR ;//低于40小时工作时长直接计算薪资
        }

        //计算税收
        if(total_salary<=TAXBREAK1){ //前300美元为15%
            taxation=total_salary*TAXRATE1 ;
        }else if(total_salary<=TAXBREAK1+TAXBREAK2){ //续150美元为20%
            taxation=TAXBREAK1*TAXRATE1+(total_salary-TAXBREAK1)*TAXRATE2 ;
        }else{ //余下的为25%
            taxation=TAXBREAK1*TAXRATE1+TAXBREAK2*TAXRATE2+
                    (total_salary-TAXBREAK1-TAXBREAK2)*TAXRATE3 ;
        }

        net_income=total_salary-taxation ; //净收入
    }
    printf("total_salary=%.4f,taxation=%.4f,net_income=%.4f \n\n",
            total_salary,taxation,net_income);
    }
    total_salary=0,taxation=0,net_income=0 ;
return 0;

}

char get_first(void)
{
int ch;
scanf(" %c",&ch);
while (getchar() != ‘\n’)
continue;
return ch;
}

char get_choice(void)
{
int ch;
printf(“Enter the number corresponding 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(“q) quit :\n”);

ch = get_first();
while ((ch < 'a' || ch > 'd') && ch != 'q')
{ 
	printf("Please respond with a, b, c, d or q.\n");
	ch = get_first();
} 
return ch;

}

8.编写一个程序, 显示一个提供加法、 减法、 乘法、 除法的菜单。 获得
用户选择的选项后, 程序提示用户输入两个数字, 然后执行用户刚才选择的
操作。 该程序只接受菜单提供的选项。 程序使用float类型的变量储存用户输
入的数字, 如果用户输入失败, 则允许再次输入。 进行除法运算时, 如果用
户输入0作为第2个数(除数) , 程序应提示用户重新输入一个新值。
#include <stdio.h>
char get_first(void) ;
float get_float(void) ;
char get_choice(void) ;

int main(void)
{ float a,b,flag;
int choice ;
while((choice=get_choice())!=‘q’)
{
switch (choice)
{
case ‘a’:
printf(“Enter first number: \n”) ;
a=get_float() ;
printf(“Enter second number: \n”) ;
b=get_float() ;
printf("%g + %g = %g\n",a,b,a+b) ;
break ;
case ‘s’:
printf(“Enter first number: \n”) ;
a=get_float() ;
printf(“Enter second number: \n”) ;
b=get_float() ;
printf("%g - %g = %g\n",a,b,a-b) ;
break ;
case ‘m’:
printf(“Enter first number: \n”) ;
a=get_float() ;
printf(“Enter second number: \n”) ;
b=get_float() ;
printf("%g * %g = %g\n",a,b,a*b) ;
break ;
case ‘d’:
printf(“Enter first number: \n”) ;
a=get_float() ;
printf(“Enter second number: \n”) ;
while((b=get_float())==0)
printf(“Enter a number other than 0 :\n”) ;
printf("%g / %g = %g\n",a,b,a/b) ;
break ;
default:
printf(“Program error!”) ;
flag=0 ;
break ;
}

    if (!flag)
    	break ;
    
}
printf("Bye.\n") ;

}

char get_choice(void)
{
int ch;
printf(“Enter the operation of your choice:\n”);
printf(“a. add \ns. subtract\n”);
printf(“m. multiply \nd. divide \nq. quit\n”);
ch = get_first();
while (ch!=‘a’ && ch != ‘q’ && ch!=‘s’ && ch!=‘m’ && ch!=‘d’)
{
printf(“Please respond with a, s, m, d or q.\n”);
ch = get_first();
}
return ch;
}

float get_float(void)
{
float input;
char ch;
while (scanf("%f", &input) != 1)
{
while ((ch = getchar()) != ‘\n’)
putchar(ch); // 处理错误输出
printf(" is not an number.\nPlease enter a ");
printf("number, such as 2.5, -1.78E8, or 3: ");
}
return input;
}

char get_first(void)
{
int ch;
scanf(" %c",&ch);
while (getchar() != ‘\n’)
continue;
return ch;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值