C Primer Plus 第六版 编程练习第八章答案 最新出炉

C Primer Plus 第六版 编程练习第八章答案 最新出炉

提示

** 第8题很好,可以检查对菜单程序设计的掌握程度,必须吃透!**

1.设计一个程序, 统计在读到文件结尾之前读取的字符数。

// 8.1
#include <stdio.h>

int main(void)
{
    double count = 0;
    int ch;

    while((ch = getchar()) != EOF)
        count++;
    printf("The number of characters: %g", count);

    return 0;  
}

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

// 8.2 -- 法一
#include <stdio.h>

int main(void)
{
    int ch;
    int count = 0;

    while((ch = getchar()) != EOF){
        count++;
        // if(count % 10 == 0)  //放在这第一行只有9个
        // printf("\n"); 
        if(ch == '\n'){
            count = 0;
            printf("\\n: %-5d", ch);
        }         
        else if(ch == '\t')
            printf("\\t: %-5d", ch);
        else if(ch < 9)
            printf("\^%c: %-5d", 64 + ch, ch);
        else
            printf("%c: %-5d", ch, ch); 
        if(count % 10 == 0)
             printf("\n");      
    }
    return 0;
}


// 8.2 -- 法二
#include <stdio.h>
#define CTRL 64
#define COL 10
#define BEFORE_T 9

int main(void)
{
    int ch;
    int count = 0;

    while((ch = getchar()) != EOF){
        count++;
        if(ch == '\n' || ch == '\t')
            printf("%s", ch == '\n' ? "\\n" : "\\t");        
        else if(ch < BEFORE_T)
            printf("\^%c", ch + CTRL);
        else
            printf("%c", ch); 
        printf(":%-5d", ch); //统一打印ASC码
        if(ch == '\n')
            count = 0;
        if(count % COL == 0)
             printf("\n");      
    }

    return 0;
}

3.编写一个程序, 在遇到 EOF 之前, 把输入作为字符流读取。 该程序要报告输入中的大写字母和小写字母的个数。 假设大小写字母数值是连续的。 或者使用ctype.h库中合适的分类函数更方便。

欢迎关注我的 微信公众号:破壳Ai,分享计算机最佳学习路径、教程和资源。成长路上,有我陪你!

// 8.3 -- 法一
#include <stdio.h>

int main(void)
{
    int ch;
    int n_lower = 0, n_upper = 0;

    printf("Enter some texts:\n");
    while((ch = getchar()) != EOF){
        if(ch >= 'a' && ch <= 'z')
            n_lower++;
        if(ch >= 'A' && ch <= 'Z')
            n_upper++;
    }
    printf("Lower letters: %d, Upper letters: %d\n",
                n_lower, n_upper);

    return 0;
}


// 8.3 -- 法二
#include <stdio.h>
#include <ctype.h>

int main(void)
{
    int ch;
    int n_lower = 0, n_upper = 0;

    printf("Enter some texts:\n");
    while((ch = getchar()) != EOF){
        if(islower(ch))
            n_lower++;
        if(isupper(ch))
            n_upper++;
    }
    printf("Lowercase letters: %d, Uppercase letters: %d\n",
                n_lower, n_upper);

    return 0;
}

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

// 8.4
#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>

int main(void)
{
    int ch;
    int n_letters = 0;
    int n_words = 0;
    bool inword = false;

    printf("Enter some words:\n");
    while((ch = getchar()) != EOF){
        if(!isspace(ch) && !ispunct(ch))
            n_letters++;
        //单词开头
        if(!isspace(ch) && !ispunct(ch) && !inword){
            inword = true;
            n_words++;
        }
        if(isspace(ch) || ispunct(ch) && inword)
            inword = false;
    }
    printf("There %d words and %d letters.\n", n_words, n_letters);
    printf("Average number of letters per word: %g\n",
            (double)n_letters / (double)n_words);

    return 0;
}

5.修改程序清单8.4的猜数字程序, 使用更智能的猜测策略。 例如, 程序最初猜50, 询问用户是猜大了、 猜小了还是猜对了。 如果猜小了, 那么下一次猜测的值应是50和100中值, 也就是75。 如果这次猜大了, 那么下一次猜测的值应是50和75的中值, 等等。 使用二分查找(binary search) 策略, 如果用户没有欺骗程序, 那么程序很快就会猜到正确的答案。

// 8.5 -- 法一
#include <stdio.h>

int main(void)
{
    char ch;
    int start = 0;
    int end = 100;
    int guess;

    printf("Pick an intrger from 1 to 100. I will try to guess it.\n");
    printf("Repond with a y if my guess is right and with");
    printf("\nan L if it is lower and with U it is upper.\n");
    guess = (start + end) / 2;
    printf("Uh...is your nunber %d?\n", guess);
    while((ch = getchar()) != 'y'){
        while(getchar() != '\n')
            continue;
        if(ch == 'U'){
            end = guess;
            guess = (start + end) / 2;
            printf("Well, then, is it %d?\n", guess);
        }          
        else if(ch == 'L'){
            start = guess;
            guess = (start + end) / 2;
            printf("Well, then, is it %d?\n", guess);
        }
        else
            printf("Sorry, I understand only y, L or U.\n");         
    }
    printf("I knew I could do it!");

    return 0;
}


// 8.5 -- 法二
#include <stdio.h>
#include <stdbool.h>
#define HIGH 100
#define LOW 0

int main(void)
{
    char ch;
    int start = LOW;
    int end = HIGH;
    int guess;
    bool input_right = true;

    guess = (start + end) / 2;
    printf("Pick an intrger from 1 to 100. I will try to guess it.\n");
    printf("Repond with a y if my guess is right and with");
    printf("\nan L if it is lower and with U it is upper.\n");
    printf("Uh...is your nunber %d?\n", guess);
    while((ch = getchar()) != 'y'){
        input_right = true;
        while(getchar() != '\n')
            continue;
        if(ch == 'U')
            end = guess;
        else if(ch == 'L')
            start = guess;
        else{
            printf("Sorry, I understand only y, L or U.\n");
            input_right = false;
        }
        if(input_right){
            guess = (start + end) / 2;
            printf("Well, then, is it %d?\n", guess); 
        }          
    }
    printf("I knew I could do it!");

    return 0;
}

6.修改程序清单8.8中的get_first()函数, 让该函数返回读取的第1个非空白字符, 并在一个简单的程序中测试。

// 8.6 -- 法一
#include <stdio.h>
#include <ctype.h>
char get_first(void);

int main(void)
{
    
    putchar(get_first());

    return 0;
}

char get_first(void)
{
    char ch;
    while(isspace(ch = getchar()))
        continue;
    while(getchar() != '\n')
        continue;

    return ch;
}


// 8.6 -- 法二
#include <stdio.h>
char get_first(void);

int main(void)
{
    
    putchar(get_first());

    return 0;
}

char get_first(void)
{
    char ch;
    
    do{
        ch = getchar();
    }while(ch == ' ' || ch == '\n' || ch == '\t');
    
    return ch;
}

7.修改第7章的编程练习8, 用字符代替数字标记菜单的选项。 用q代替5作为结束输入的标记。

// 8.7 -- 7.8型2 (法4):循环计算正确输入后的各值
#include <stdio.h>
#include <stdbool.h>
void print(void);
char get_choice(void);
char get_first(void);
#define PAY_RATE1 8.75
#define PAY_RATE2 9.33
#define PAY_RATE3 10.00
#define PAY_RATE4 11.20
#define TIME_BASE 40
#define OVERTIME 1.5
#define BREAK1 300
#define BREAK2 450
#define RATE1 0.15
#define RATE2 0.20
#define RATE3 0.25

int main(void)
{
    int choice;
    double pay_rate;
    double hours;
    double gross, tax, net;

    while((choice = get_choice()) != 'q'){
        switch(choice){
            case 'a': pay_rate = PAY_RATE1;
                      break;
            case 'b': pay_rate = PAY_RATE2;
                      break;
            case 'c': pay_rate = PAY_RATE3; 
                      break;
            case 'd': pay_rate = PAY_RATE4; 
                      break;
            default:  printf("Program error!\n");
                      break;
        }
        printf("Enter your work hours in a week: ");
        scanf("%lf", &hours);
        if(hours > TIME_BASE)
            hours = TIME_BASE + (hours - TIME_BASE) * OVERTIME;
        gross = hours * pay_rate;
        if(gross < BREAK1)
            tax = gross * RATE1;
        else if(gross < BREAK2)
            tax = BREAK1 * RATE1 + (gross - BREAK1) * RATE2;
        else
            tax = BREAK1 * RATE1 + (BREAK2 - BREAK1) * RATE2\
                + (gross - BREAK2) * RATE3;
        net = gross - tax;
        printf("Gross: %.2lf, tax: %.2lf, net: %.2lf\n", gross, tax, net);      
    }
 
    return 0;
}

void print(void)
{
    printf("\n*****************************************************************\n");
    printf("Enter the letter 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");
    printf("******************************************************************\n");
}

char get_choice(void)
{
    int ch;
    
    print();
    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;
}

char get_first(void)
{
    int ch;
    
    // ch = getchar();
    // whilech == ' ' || ch == '\n' || ch == '\t')
    //     ch = getchar();

    //跳过非空字符
    do{
        ch = getchar();
    }while(ch == ' ' || ch == '\n' || ch == '\t');
    //舍弃剩余字符
    while(getchar() != '\n')
        continue;
    
    return ch;
}

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

Enter the operation of your choice:
a. add s. subtract
m. multiply d. divide q. quita
Enter first number: 22 .4
Enter second number: one
one is not an number.
Please enter a number, such as 2.5, -1.78E8, or 3: 1
22.4 + 1 = 23.4
Enter the operation of your choice:
a. add s. subtract
m. multiply d. divide 559
q. quitd
Enter first number: 18.4
Enter second number: 0
Enter a number other than 0: 0.2
18.4 / 0.2 = 92
Enter the operation of your choice:
a. add s. subtract
m. multiply d. divide
q. quit
q
Bye.

欢迎关注我的 微信公众号:破壳Ai,分享计算机最佳学习路径、教程和资源。成长路上,有我陪你!

// 8.8
#include <stdio.h>
#include <stdbool.h>
void show_menu(void);
char menu_choice(void);
char get_first(void);
float input_number(void);

int main(void)
{
    char choice;
    float num1, num2;

    while((choice = menu_choice()) != 'q'){
        //输入两个浮点数
        printf("Enter first number: ");
        num1 = input_number();
        printf("Enter second number: ");
        num2 = input_number();

        //加减乘除
        switch(choice){
            case 'a': printf("%g + %g = %g\n", num1, num2, num1 + num2);
                      break;
            case 's': printf("%g - %g = %g\n", num1, num2, num1 - num2);
                      break;
            case 'm': printf("%g * %g = %g\n", num1, num2, num1 * num2);
                      break;
            case 'd': 
                    if(!num2){
                        printf("Enter a number other than 0: ");
                        num2 = input_number();
                    }
                    printf("%g / %g = %g\n", num1, num2, num1 / num2);
                        break;
            default:  printf("Program error!\n");
                      break;    
        }
    }
    printf("Bey.");
    
    return 0;
}

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

char menu_choice(void)
{
    int ch;
    
    show_menu();
    ch = get_first();
    while(ch != 'a' && ch != 's' && ch != 'm' && ch != 'd' && ch != 'q'){
        printf("Please respond with a, s, m, d or q.\n");
        ch = get_first();   //这里需要再一次使用get_first()获得输入值
    }
    return ch;
}

char get_first(void)
{
    int ch;

    //跳过非空字符
    do{
        ch = getchar();
    }while(ch == ' ' || ch == '\n' || ch == '\t');
    //舍弃剩余字符
    while(getchar() != '\n')
        continue;
    
    return ch;
}

float input_number(void)
{
    float num;
    char ch;

    while(scanf("%f", &num) != 1){
        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: ");
        //scanf("%f", &num);  这里不能再使用scanf()获取输入值了,因为while()里已经包含了
    }
    while(getchar() != '\n')
        continue;
    return num;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值