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;
}