玛卡巴卡的卡巴卡玛 发表于 2024-10-31 19:46:25

《C Primer Plus》编程训练—第14章

《C Primer Plus》编程训练

第14章

1.exercise1.c

计划一个结构模板存储一个月份名、该月份名的3个字母缩写、该月的天数以及月份号。定义一个数组,内含12个结构并初始化为一个年份(非闰年)。假设在全部函数的外部声明了该结构模板和一个该结构范例的数组。编写一个函数,用户提供月份号,该函数就返回一年中到该月为止(包括该月)的总天数。用月份名的拼写代替月份号(别忘了利用strcmp())。在一个简单的程序中测试该函数。
//exercise14.1
#include <stdio.h>
#include <ctype.h>
#include <string.h>

struct month {
   
    char name;
    char abbrev;
    int days;
    int monumb;
};//结构模板
const struct month months = {
   
    {
   "January", "Jan", 31, 1},
    {
   "February", "Feb", 28, 2},
    {
   "March", "Mar", 31, 3},
    {
   "April", "Apr", 30, 4},
    {
   "May", "May", 31, 5},
    {
   "June", "Jun", 30, 6},
    {
   "July", "Jul", 31, 7},
    {
   "August", "Aug", 31, 8},
    {
   "September", "Sep", 30, 9},
    {
   "October", "Oct", 31, 10},
    {
   "November", "Nov", 3, 11},
    {
   "December", "Dec", 31, 12}
};//结构数组
int days(char * input);//获取月份名,计算天数
int main(void)
{
   
    char input;
    int total_days;

    printf("请输入月份名:(按q退出程序)\n");
    while (scanf("%s",input) == 1 && input != 'q')//输入q才停止循环
    {
   
      total_days = days(input);//调用函数
      if (total_days > 0) //总天数大于0,说明有对应月份号
      {
   
            printf("总天数是:%d\n",total_days);
      }
      else
      {
   
            printf("输入有误。\n");
      }
      printf("请输入下一个月份名:(按q退出程序)\n");
    }
    printf("程序结束\n");

    return 0;
}
int days(char * input)
{
   
    int i;
    int total = 0;
    int num = 0;

    input = toupper(input);//第一个字母转成大写
    for (i = 1; input != '\0'; i++) //循环到输入为止,都转为小写字母
    {
   
      input = tolower(input);
    }
    for (i = 0; i < 12; i++)
    {
   
      if (strcmp(input, months.name) == 0) //和结构数组每一个元素的名字比较
      {
   
            num = months.monumb;//找到对应月份,把月份号赋值给num
            break;
      }
    }
    if (num == 0) //没有对应月份号
    {
   
      total = 0;
    }
    else
    {
   
      for (i = 0; i < num; i++) //有对应月份号
      {
   
            total += months.days;//求和
      }
    }
    return total;//返回总天数
}
输入示例:
请输入月份名:(按q退出程序)
febRuary
总天数是:59
请输入下一个月份名:(按q退出程序)
q
程序结束
2.exercise2.c

编写一个函数,提示用户输入日、月和年。月份可以是月份号、月份名或月份名缩写。然后该程序应返回一年中到用户指定日子(包括这一天)的总天数。
//exercise14.2
#include <stdio.h>
#include <ctype.h>
#include <string.h>

struct month {
   
    char name;
    char abbrev;
    int days;
    int monumb;
};//结构模板
struct month months = {
   
    {
   "January", "Jan", 31, 1},
    {
   "February", "Feb", 28, 2},
    {
   "March", "Mar", 31, 3},
    {
   "April", "Apr", 30, 4},
    {
   "May", "May", 31, 5},
    {
   "June", "Jun", 30, 6},
    {
   "July", "Jul", 31, 7},
    {
   "August", "Aug", 31, 8},
    {
   "September", "Sep", 30, 9},
    {
   "October", "Oct", 31, 10},
    {
   "November", "Nov", 3, 11},
    {
   "December", "Dec", 31, 12}
};//结构数组
int days(int day, char * input);//获取月份名,计算天数
void leapyear(int year);
int main(void)
{
   
        int day, year;
    char input;
    int total_days;

    printf("请输入日,月份名,年:(按q退出程序)\n");
    while (scanf("%d %s %d", &day, input, &year) == 3 && input != 'q')
    {
   
            leapyear(year);
      total_days = days(day, input);//调用函数
      if (total_days > 0) //总天数大于0,说明有对应月份号
      {
   
            printf("总天数是:%d\n",total_days);
      }
      else
      {
   
            printf("输入有误。\n");
      }
      months.days = 28;//将2月份重置为28天
      printf("请输入下一个日,月份名,年:(按q退出程序)\n");
    }
    printf("程序结束\n");

    return 0;
}
int days(int day, char * input)
{
   
    int i;
    int total = 0;
    int num = 0;

    input = toupper(input);//第一个字母转成大写
    for (i = 1; input != '\0'; i++) //循环到输入为止,都转为小写字母
    {
   
      input = tolower(input);
    }
    for (i = 0; i < 12; i++)
    {
   
      if (strcmp(input, months.name) == 0) //和结构数组每一个元素的名字比较
      {
   
            num = months.monumb;//找到对应月份,把月份号赋值给num
            break;
      }
    }
    if (num == 0) //没有对应月份号
    {
   
      total = 0;
    }
    else
    {
   
      for (i = 0; i < num; i++) //有对应月份号
      {
   
            total += months.days;//求和
      }
      total += day;//再加上日期数
    }
    return total;//返回总天数
}
void leapyear(int year)
{
   
        if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)//判断是否为闰年
        {
   
                months.days = 29;//闰年2月为29天
        }
}
输出示例:
请输入日,月份名,年:(按q退出程序)
1 march 2020
总天数是:92
请输入下一个日,月份名,年:(按q退出程序)
1 march 2019
总天数是:91
请输入下一个日,月份名,年:(按q退出程序)
q
程序结束
没有做过多的输入验证,默认是按照正常输入。
3.exercise3.c

修改程序manybook.c中的图书目录程序,使其按照输入图书的顺序输出图书的信息,然后按照书名的字母顺序输出图书的信息,末了按照价格的升序输出图书的信息。
//exercise14.3
#include <stdio.h>
#include <string.h>

char * s_gets(char * st, int n);
#define MAXTITL   40
#define MAXAUTL   40
#define MAXBKS   100            /* 书籍的最大数量*/

struct book {
                        /* 建立book模板   */
    char title;
    char author;
    float value;
};
void print(struct book library, int count);//原样打印
void print_al(struct book library, int count);//按字母顺序打印
void print_price(struct book library, int count);//按价格升序打印
int main(void)
{
   
    struct book library; /* book类型的结构数组 */
    int count = 0;
   
    printf("请输入书名:\n");
    printf("在开始处按enter键结束程序。\n");
    while (count < MAXBKS && s_gets(library.title, MAXTITL) != NULL
         && library.title != '\0')
    {
   
      printf("输入作者名:\n");
      s_gets(library.author, MAXAUTL);
      printf("输入书的价格\n");
      scanf("%f", &library.value);
      while (getchar() != '\n')
            continue;          /* 清理输入行*/
      if (count < MAXBKS)
            printf("输入下一本书的名字:\n");
    }
   
    if (count > 0)
    {
   
            printf("这是你的书的顺序:\n");
      print(library, count);
      print_al(library, count);
      print_price(library, count);
    }
    else
            printf("没有书。\n");
   
    return 0;
}

char * s_gets(char * st, int n)
{
   
    char * ret_val;
    char * find;
   
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    {
   
      find = strchr(st, '\n');   // 查找换行符
      if (find)                  // 如果地址不是NULL,
            *find = '\0';          // 在此处放置一个空字符
      else
            while (getchar() != '\n')
                continue;          // 处理输入行中剩余的字符
    }
    return ret_val;
}
void print(struct book library, int count)
{
   
        int index;
   
        for (index = 0; index < count; index++)
        {
   
                printf("%s by %s: $%.2f\n", library.title,
                   library.author, library.value);
        }      
}
void print_al(struct book library, int count)
{
   
        struct book temp;//标记
        int index;
    int i;
   
    printf("书按字母顺序输出:\n");
        for (index = 0; index < count - 1; index++)//冒泡排序
    {
   
      for (i = index + 1; i < count; i++)
      {
   
              if (strcmp(library.title, library.title) > 0)
                                //后面的书的字母排在前面的书的前面
                        {
   
                                temp = library;//交换
                                library = library;
                                library = temp;
                        }
                }
        }
        print(library, count);//打印排序后的
}
void print_price(struct book library, int count)
{
   
        struct book temp;
        int index;
    int i;
   
    printf("书按价格顺序输出:\n");
        for (index = 0; index < count - 1; index++)
    {
   
      for (i = index + 1; i < count; i++)
      {
   
              if (library.value > library.value)
                        //前面的书价格高于后面的书
                        {
   
                                temp = library;
                                library = library;
                                library = temp;
                        }
                }
        }
        print(library, count);
}
输出示例:
请输入书名:
在开始处按enter键结束程序。
c study
输入作者名:
sttphen
输入书的价格
56
输入下一本书的名字:
python
输入作者名:
peter
输入书的价格
23
输入下一本书的名字:
java
输入作者名:
lily
输入书的价格
35
输入下一本书的名字:

这是你的书的顺序:
c study by sttphen: $56.00
python by peter: $23.00
java by lily: $35.00
书按字母顺序输出:
c study by sttphen: $56.00
java by lily: $35.00
python by peter: $23.00
书按价格顺序输出:
python by peter: $23.00
java by lily: $35.00
c study by sttphen: $56.00
4.exercise4.c

编写一个程序,创建一个有两个成员的结构模板:
a. 第1个成员是社会保险号,第2个成员是一个有3个成员的结构,第1个成员代表名,第2个成员代表中间名,第3个成员表现姓。创建并初始化一个内含5个该范例结构的数组。该程序以下面的格式打印数据:
Dribble, Flossie M. – 302039823
如果有中间名,只打印它的第1个字母,背面加一个点(.); 如果没有中间名,则不用打印点。编写一个程序举行打印,把结构数组转达给这个函数。
b. 修改a部分,转达结构的值而不是结构的地址。
//exercise14.4a
#include <stdio.h>
#include <string.h>
#define LEN 20

struct names {
   
        char fname;
        char mname;
        char lname;
};

struct message {
   
        char sonum;
        struct names name;
};
char * s_gets(char * st, int n);
void print(const struct message num[], int n);
int main(void)
{
   
        struct message num;//结构数组
        int count = 0;
       
        printf("请输入保险号:\n");
    printf("在开始处按enter键结束程序。\n");
    while (count < 5 && s_gets(num.sonum, LEN) && num.sonum != '\0')
    {
   //输入不超过5个,或者直接输入enter退出
            printf("请输入名:\n");
            s_gets(num.name.fname, LEN);
            printf("请输入中间名:\n");
            s_gets(num.name.mname, LEN);
            printf("请输入姓:\n");
            s_gets(num.name.lname, LEN);
            if (count < 5)//输入不超过5个,继续输入
            {
          
                    printf("请输入下一个保险号:\n");
                }
                count++;
        }
        if (count > 0)//输入了成员
        {
   
                printf("以下是所有成员:\n");
                print(num, count);       
        }
        else//没输入成员
        {
   
                printf("没有成员。\n");
        }
        printf("程序结束。\n");
       
        return 0;
}
char * s_gets(char * st, int n)
{
   
    char * ret_val;
    char * find;
   
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    {
   
      find = strchr(st, '\n');   // 查找换行符
      if (find)                  // 如果地址不是NULL,
            *find = '\0';          // 在此处放置一个空字符
      else
            while (getchar() != '\n')
                continue;          // 处理输入行中剩余的字符
    }
    return ret_val;
}
void
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 《C Primer Plus》编程训练—第14章