《C Primer Plus 》第六版 习题 第八章

缓冲区 buffer

用户按下Enter键之前不会重复打印刚输入的字符,这种输入形式属于缓冲输入

在这里插入图片描述

缓冲分两种:

  1. 完全缓冲I/O
    当缓冲区被填满时才刷新缓冲区(内容被发送至目的地),通常出现在文件输入中。
    缓冲区大小取决于系统,常见大小是 512 byte4096 byte
  2. 行缓冲I/O
    在出现换行符时才刷新缓冲区。键盘输入通常是行缓冲输入。在按下Enter后刷新缓冲区。

早先缓不缓冲是交给编译器决定的,后来从 ANSI C 开始默认都是使用缓冲区的。

8.11.1

/*
 * @Author       : TCP404
 * @Description  : 设计一个程序,统计在读到文件结尾之前读取的字符数。
 * @version      : 
 * @Date         : 2020-04-21 14:45:14
 * @LastEditors  : TCP404
 * @LastEditTime : 2020-04-21 15:31:40
 */
#include <stdio.h>

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

    printf("Enter some word, press <Ctrl+C> to exit.\n");
    while ((ch = getchar()) != EOF)
        if (ch != '\n')
            count++;
    printf("There are %d character", count);

    return 0;
}

在这里插入图片描述

8.11.2

/*
 * @Author       : TCP404
 * @Description  : 编写一个程序,在遇到EOF之前,把输入作为字符流读取。程序要打印每个输入的字符及其响应的ASCII十进制的值。
 * @version      : 
 * @Date         : 2020-04-21 15:41:09
 * @LastEditors  : TCP404
 * @LastEditTime : 2020-04-21 16:11:11
 */
#include <stdio.h>

int main(void)
{
    char ch = 0;
    int tenCount = 0;
    while ((ch = getchar()) != EOF)
    {
        ++tenCount;
        if (tenCount > 10)
        {
            putchar('\n');
            tenCount = 0;
        }

        switch (ch)
        {
        case 10:
            putchar('\\');
            putchar('n');
            printf(":10\t");
            break;
        case 9:
            putchar('\\');
            putchar('t');
            printf(":09\t");
            break;
        case 32:
            putchar('_');
            printf(":32\t");
            break;
        default:
            putchar(ch);
            printf(":%d\t", ch);
            break;
        }
    }

    return 0;
}

在这里插入图片描述

8.11.3

/*
 * @Author       : TCP404
 * @Description  : 编写一个程序,在遇到EOF之前,把连续输入作为字符流读取。
 *                 该程序中要报告大写字母和小写字母的个数。
 *                 可以使用ctype.h库中合适的分类函数更方便。
 * @version      : 
 * @Date         : 2020-04-21 16:14:03
 * @LastEditors  : TCP404
 * @LastEditTime : 2020-04-21 16:25:10
 */
#include <stdio.h>
#include <ctype.h>
int main(void)
{
    char ch = 0;
    int lowerCount = 0;
    int supperCount = 0;

    printf("\nPlease enter some things: \n");

    while ((ch = getchar()) != EOF)
    {
        if (islower(ch))
            lowerCount++;
        else if (isupper(ch))
            supperCount++;
    }

    printf("There has %d lower and %d supper.", lowerCount, supperCount);
    return 0;
}

在这里插入图片描述

8.11.4

/*
 * @Author       : TCP404
 * @Description  : 编写一个程序,在遇到EOF之前,把输入作为字符流读取。该程序要报告平均每个单词的字母数。
 *                 不要把空白统计为单词的字母,标点符号也不要。
 * @version      : 
 * @Date         : 2020-04-21 16:27:13
 * @LastEditors  : TCP404
 * @LastEditTime : 2020-04-21 16:50:29
 */
#include <stdio.h>
#include <ctype.h>
int main(void)
{
    char ch = 0;
    int count = 0;
    printf("Please enter some word: \n");
    while ((ch = getchar()) != EOF)
    {
        if (isalnum(ch))
        {
            putchar(ch);
            count++;
        }
        if (ch == 32)
        {
            printf(":%d ", count);
            count = 0;
        }
    }

    return 0;
}

在这里插入图片描述

8.11.5

/*
 * @Author       : TCP404
 * @Description  : 修改8.4的猜数字程序,使用更智能的猜测策略,例如二分查找法。
 * @version      : 
 * @Date         : 2020-04-21 16:52:02
 * @LastEditors  : TCP404
 * @LastEditTime : 2020-04-21 18:27:10
 */

#include <stdio.h>

void find();
int main(void)
{

    int guess = 100;
    char ch = 0;

    printf("Pick an integer from 1 to 100. I will try to guess it.\n");
    printf("Respond with a \'y\' if my guess is right and with an \'n\' if it is wrong.\n");
    printf("Un...is your number %d?\n", guess);

    while ((ch = getchar()) != 'q')
        if (ch == 'n')
        {
            find(guess);
        }
        else
        {
            printf("Awesome!!!");
            break;
        }

    return 0;
}

void find(int guess)
{
    char respond = 0;

    int low = 0;
    int heigh = guess;

    while (low <= heigh)
    {
        int mid = (low + heigh) / 2;

        printf("Well, then, is it %d\n", mid);
        scanf("%c", &respond);
    yes:
        if (respond != 'y')
        {
            printf("More or Less ? [m/l]");
            fflush(stdin);
            scanf("%c", &respond);

            switch (respond)
            {
            case 'm':
                heigh = mid;
                break;
            case 'l':
                low = mid;
                break;
            case 'y':
                goto yes;
                break;
            default:
                printf("Sorry, I understand only \'y\' , \'n\' , \'m\' and \'l\'.\n");
                break;
            }
        }
        else
        {
            printf("Awesome!!!");
            break;
        }
    }
}

在这里插入图片描述

8.11.6

懒得写。

8.11.7

/*
 * @Author       : TCP404
 * @Description  : 改写第7章编程练习8,把菜单的1234改成abcd,用q退出替代5的退出。
 * @version      : 
 * @Date         : 2020-04-21 21:28:39
 * @LastEditors  : TCP404
 * @LastEditTime : 2020-04-21 21:36:37
 */


#include <stdio.h>
#define ST_WORK_TIME 40                            //一周基本工时
#define ST_SALARY_WEEK i_choice * 40               //一周满40小时标准工薪
#define TAX1 d_salary * 0.15                       //首300以内15%
#define TAX2 TAX1 + (d_salary - 300) * 0.2         //续150以内20%
#define TAX3 TAX1 + TAX2 + (d_salary - 450) * 0.25 //余下的25%

int main()
{
    char i_choice;        // i_选择:用来存放用户输入的时薪选项
    int i_work_time;     // i_工作时间:用来存放用户输入的一周工作时间
    double d_salary;     // d_薪资:用来存放 时间*时薪 的变量
    double d_tax;        // d_税率:用来存放用户应缴纳的税金
    double d_net_income; // d_净收入:用来存放用户最后的净收入

a:
    printf("********************************************************************\n");
    printf("Enter the number corresponding to the desired pay rate or action  ->\n\n");
    printf("a) $8.75/h \t\t b)9.33/h \n");
    printf("c) $10.0/h \t\t d)11.2/h \n");
    printf("q) quit\n");
    printf("********************************************************************\n");
    printf("->");
    fflush(stdin);
    scanf("%c", &i_choice);

    switch (i_choice)
    {
    case 97:
        printf("Please enter your work hours a week:");
        scanf("%d", &i_work_time);
        break;
    case 98:
        printf("Please enter your work hours a week:");
        scanf("%d", &i_work_time);
        break;
    case 99:
        printf("Please enter your work hours a week:");
        scanf("%d", &i_work_time);
        break;
    case 100:
        printf("Please enter your work hours a week:");
        scanf("%d", &i_work_time);
        break;
    case 113:
        goto b;
        break;
    default:
        printf("Please enter number in 1 ~ 5 ->\n");
        goto a;
    }

    if (i_work_time <= 40)
    {
        d_salary = i_choice * i_work_time;
    }
    else
    {
        d_salary = ST_SALARY_WEEK + (i_work_time - ST_WORK_TIME) * i_choice * 1.5;
    }
    printf("\n\nYour salary is : \t$%.2f\n", d_salary);

    //计算税率
    if (d_salary <= 300)
    {
        d_tax = TAX1;
    }
    else if (d_salary <= 450)
    {
        d_tax = TAX2;
    }
    else
    {
        d_tax = TAX3;
    }
    printf("You need to pay taxes :\t $%.2f\n", d_tax);

    d_net_income = d_salary - d_tax;

    printf("Your net income is :\t $%.2f\n\n\n\n", d_net_income);

    goto a;

b:
    printf("\n\nSee you !\n");
    return 0;
}

在这里插入图片描述

8.11.8

/*
 * @Author       : TCP404
 * @Description  : 写个程序,让用户选择加减乘除,先选,选错重新选,用float存要计算的数字,除法第二个不能为0,输错重新来
 * @version      : 
 * @Date         : 2020-04-21 21:43:33
 * @LastEditors  : TCP404
 * @LastEditTime : 2020-04-21 22:35:46
 */
#include <stdio.h>
enum BOOL
{
    TRUE = 1,
    FALSE = 0
};
void typeNum(enum BOOL divide);
float addition(float head, float end);
float subtraction(float head, float end);
float multiplication(float head, float end);
float division(float head, float end);

float head_num = 0;
float end_num = 0;
int main(void)
{
    char i_choice = 0;
again:
    printf("********************************************************************\n");
    printf("Enter a/b/c/d to choice a way of compute, q to quit ->\n\n");
    printf("a) + \t\t b) - \n");
    printf("c) * \t\t d) / \n");
    printf("q) quit\n");
    printf("********************************************************************\n");
    printf("->");
rechoice:
    fflush(stdin);
    scanf("%c", &i_choice);

    switch (i_choice)
    {
    case 'a':
        typeNum(FALSE);
        printf("%.1f + %.1f = %.1f\n\n", head_num, end_num, addition(head_num, end_num));
        break;
    case 'b':
        typeNum(FALSE);
        printf("%.1f - %.1f = %.1f\n\n", head_num, end_num, subtraction(head_num, end_num));
        break;
    case 'c':
        typeNum(FALSE);
        printf("%.1f * %.1f = %.1f\n\n", head_num, end_num, multiplication(head_num, end_num));
        break;
    case 'd':
        typeNum(TRUE);
        printf("%.1f / %.1f = %.1f\n\n", head_num, end_num, division(head_num, end_num));
        break;
    case 'q':
        goto quit;
        break;
    default:
        printf("Input Error! Retype!\n");
        goto rechoice;
        break;
    }
    goto again;
quit:
    printf("See you!");
    return 0;
}

void typeNum(enum BOOL divide)
{
    printf("Type the first number: ");
    fflush(stdin);
    while (scanf("%f", &head_num) != 1)
    {
        printf("Input Error!!! Retype!!!\n");
        fflush(stdin);
    }

re_sec_num:
    printf("Type the second number: ");
    fflush(stdin);
    while (scanf("%f", &end_num) != 1)
    {
        printf("Input Error!!! Retype!!!\n");
        fflush(stdin);
    }
    if (divide && end_num == 0)
    {
        printf("The denominator cannot be zero! Retype!\n");
        goto re_sec_num;
    }
}

float addition(float head, float end)
{
    return head + end;
}
float subtraction(float head, float end)
{
    return head - end;
}
float multiplication(float head, float end)
{
    return head * end;
}
float division(float head, float end)
{
    return end == 0 ? 0 : head / end;
}

在这里插入图片描述

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TCP404

老板大方~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值