C语言 第8章 编程练习

/* 第1题
1.设计一个程序,统计在读到文件结尾之前读取的字符数。
*/
#include <stdio.h>
int main(void)
{
    int 字符;
    int 统计 = 0;

    printf("请输入一些字符(Ctrl+Z退出):\n");
    while((字符 = getchar()) != EOF)    // EOF文件结尾
    {
        统计++;
    }
    printf("字符: %d.\n", 统计);

    return 0;
}

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

    printf("请输入一些字符(Ctrl+z退出):\n");
    while((字符 = getchar()) != EOF)
    {
        if(i++ == 10)
        {
            putchar('\n');
            i = 1;
        }
        // ↓空格的十进制ASCII码;
        if(字符 >= 32)
        {
            printf(" \'%c\' - %3d ", 字符, 字符);
        }
        else if(字符 == '\n')
        {
            printf(" \\n - \\n\n ");
            i = 0;
        }
        else if(字符 == '\t')
        {
            printf(" \\t - \\t ");
        }
        else
        {
            printf(" \'%c\' - ^%c ", 字符, 字符 + 64);
        }
    }
    puts("完毕!"); // puts()写字符串函数

    return 0;
}

/* 第3题
3.编写一个程序,在遇到EOF文件结尾之前,把输入作为字符流读取。
该程序要报告输入中的大写字母和小写字母的个数。
假设大小写字母数值是连续的。
或者使用ctype.h库中合适的分类函数更方便。
*/
#include <stdio.h>
#include <ctype.h>
int main(void)
{
    int 字符;
    unsigned int 大写字母 = 0;
    unsigned int 小写字母 = 0;
    unsigned int 其它字符 = 0;

    printf("请输入一些字符(Ctrl+z退出):\n");
    while((字符 = getchar()) != EOF)
    {
        // ↓isupper()是否大写字母
        if(isupper(字符))
        {
            大写字母++;
        }
        // ↓islower()是否小写字母
        else if(islower(字符))
        {
            小写字母++;
        }
        else
        {
            其它字符++;
        }
    }
    printf("大写字母:%u.\n", 大写字母);
    printf("小写字母: %u.\n", 小写字母);
    printf("其它字符: %u.\n", 其它字符);

    return 0;
}

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

    printf("请输入一些单词(Ctrl+z退出):\n");
    while((字符 = getchar()) != EOF)
    {
        // ↓ 是否标点符号ispunct()
        if(ispunct(字符))
        {
            continue;
        }
        // ↓ 是否字母isalpha()
        if(isalpha(字符))
        {
            字母++;
        }
        // ↓ 是否空白符号isspace()
        if(!isspace(字符) && !空白符)
        {
            空白符 = 真;
            单词++;
        }
        // ↓ 是否空白符号isspace()
        if(isspace(字符) && 空白符)
        {
            空白符 = 假;
        }
    }
    统计 = (float)字母 / 单词;
    printf("单词总数:%d.\n", 单词);
    printf("字母总数:%d.\n", 字母);
    printf("平均每个单词的字母数: %g.\n", 统计);

    return 0;
}

/* 第5题
5.修改程序清单8.4的猜数字程序,使用更智能的猜测策略。
例如,程序最初猜50,询问用户是猜大了、猜小了还是猜对了。
如果猜小了,那么下一次猜测的值应是50和100中值,也就是75。
如果这次猜大了,那么下一次猜测的值应是50和75的中值,等等。
使用二分查找(binary search)策略,如果用户没有欺骗程序,
那么程序很快就会猜到正确的答案。
*/
#include <stdio.h>
#include <ctype.h>
int main(void)
{
    int 太高 = 100;
    int 太低 = 1;
    int 猜 = (太高 + 太低) / 2;
    int 响应;

    printf("从 1 到 100 中选择一个整数。我会尝试猜测它。\n"
               "如果我的猜测是正确的,用 y 响应,\n"
               "如果太高,用 h 表示,\n如果太低,用 l 表示。\n");
    printf("你的号码是 %d 吗?\n", 猜);
    while((响应 = getchar()) != 'y')
    {
        if(响应 == '\n')
        {
            continue;
        }
        if(响应 != 'h' && 响应 != 'l')
        {
            printf("我不明白那个回应。 \n");
            printf("请输入 h 表示太高,"
                       "l 表示太低,或 y 表示正确。\n");
            continue;
        }
        // ↓tolower()转小写字母
        if(响应 == 'h')
        {
            太高 = 猜 - 1;
        }
        else if(响应 == 'l')
        {
            太低 = 猜 + 1;
        }
        猜 = (太高 + 太低) / 2;
        printf("那么,是%d吗?\n", 猜);
    }
    printf("我知道我能做到!\n");

    return 0;
}

/* 第6题
6.修改程序清单8.8中的 取首个() 函数,
让该函数返回读取的第1个非空白字符,并在一个简单的程序中测试。
*/
#include <stdio.h>
#include <ctype.h>
#define 终止 '#'
int 取首个(void);
int main(void)
{
    int 字符;

    printf("请输入一些字符('#'退出):\n");
    while((字符 = 取首个()) != 终止)
    {
        printf("结果:%c\n", 字符);
        printf("您可以再次输入('#'退出):\n");
    }
    printf("完毕!\n");

    return 0;
}

int 取首个(void)
{
    int 字符;

    do
    {
        字符 = getchar();
    }
    while(isspace(字符)); // isspace()测空白符
    while(getchar() != '\n')
    continue;

    return 字符;
}

/* 第7题
7.修改第7章的编程练习8,用字符代替数字标记菜单的选项。
用q代替5作为结束输入的标记。
*/
#include <stdio.h>
#include <ctype.h>
#include <stdio.h>
#define 小时8元 8.75  // 每小时8.75美元
#define 小时9元 9.33  // 每小时9.33美元
#define 小时10元 10.00 // 每小时10.00美元
#define 小时11元 11.20 // 每小时11.20美元
#define 每周工时 40     // 每周工时
#define 加班倍数 1.5   // 1.5倍时间
#define 工资1 300       // 工资等级1
#define 工资2 150       // 工资等级2
#define 税率1 0.15     // 基本工资税率
#define 税率2 0.20     // 加班工资税率
#define 税率3 0.25     // 超出工资税率
int 取首个(void);
void 菜单(void);
int main(void) {
    double 工时;
    double 总工资;
    double 净收入;
    double 税款;
    double 支付;
    char 响应;

    菜单();
    while ((响应 = 取首个()) != 'q') {
        if (响应 == '\n')
            continue;
        响应 = tolower(响应);
        switch (响应) {
        case 'a':
            支付 = 小时8元;
            break;
        case 'b':
            支付 = 小时9元;
            break;
        case 'c':
            支付 = 小时10元;
            break;

        case 'd':
            支付 = 小时11元;
            break;
        default:
            printf("请输入a、b、c、d或q。\n");
            菜单();
            continue; // 转到循环的开头
        }
        printf("输入本周的工作小时数:");
        scanf("%lf", &工时);
        if (工时 <= 每周工时)
            总工资 = 工时 * 支付;
        else
            总工资 = 每周工时 * 支付 + (工时 - 每周工时) * 支付 * 加班倍数;
        if (总工资 <= 工资1)
            税款 = 总工资 * 税率1;
        else if (总工资 <= 工资1 + 工资2)
            税款 = 工资1 * 税率1 + (总工资 - 工资1) * 税率2;
        else
            税款 = 工资1 * 税率1 + 工资2 * 税率2 + (总工资 - 工资1 - 工资2) * 税率3;
        净收入 = 总工资 - 税款;
        printf("总工资: $%.2f; 税款: $%.2f; 净收入: $%.2f\n", 总工资, 税款,
               净收入);
        菜单();
    }
    printf("完成。\n");

    return 0;
}
void 菜单(void) {
    printf("********************************************************"
           "*********\n");
    printf("输入与所需工资率或操作对应的字母:\n");
    printf("a) $%4.2f/hr b) $%4.2f/hr\n", 小时8元,
           小时9元);
    printf("c) $%5.2f/hr d) $%5.2f/hr\n", 小时10元,
           小时11元);
    printf("q) 退出\n");
    printf("********************************************************"
           "*********\n");
}
int 取首个(void) {
    int 字符;
    字符 = getchar();
    while (isspace(字符))
        字符 = getchar();
    while (getchar() != '\n')
        continue;
    return 字符;
}

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

int 取首个(void);
int 获取选项(void);
float 取小数(void);

int main(void)
{
    int 统计;
    float i, j;

    while((统计 = 获取选项()) != 'q')
    {
        printf("输入第一个数字:");
        i = 取小数();
        printf("输入第二个数字:");
        j = 取小数();
        switch(统计)
        {
            case 'a':
            {
                printf("%g + %g = %g\n", i, j, i + j);
                break;
            }
            case 's':
            {
                printf("%g - %g = %g\n", i, j, i - j);
                break;
            }
            case 'm':
            {
                printf("%g * %g = %g\n", i, j, i * j);
                break;
            }
            case 'd':
            {
                while(fabs(j) <= 1e-6)
                {
                    //↑判断float型浮点数是否为0;
                    printf("输入 0 以外的数字:");
                    j = 取小数();
                }
                printf("%g / %g = %g\n", i, j, i / j);
                break;
            }
        }
    }
    printf("再见!\n");

    return 0;
}

int 取首个(void)
{
    int 字符;

    do
    {
        字符 = islower(getchar());
    }
    while(isspace(字符));
    while(getchar() != '\n')
    continue;

    return 字符;
}

int 获取选项(void)
{
    int 字符;

    printf("输入选项:\n");
    printf("a. 加           s. 减\n");
    printf("m. 乘           d. 除\n");
    printf("q. 退出\n");
    字符 = 取首个();

    while(字符 != 'a' && 字符 != 's' && 字符 != 'm' && 字符 != 'd' && 字符 != 'q')
    {
        printf("请输入a、s、m、d或q:");
        字符 = 取首个();
    }
    return 字符;
}

float 取小数(void)
{
    int 字符;
    float 输入;

    while(scanf("%f", &输入) != 1)
    {
        while((字符 = getchar()) != '\n')
        {
            putchar(字符);
        }
        printf(" 不是一个数字,\n");
        printf("请输入一个数字,例如 2.5、-1.78E8 或 3:");
    }
    return 输入;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值