首页 > 其他 > 详细

通讯录的实现

时间:2021-04-11 15:56:45      阅读:15      评论:0      收藏:0      [点我收藏+]
第一:实现要点

1.1 创建一个项目, 并创建相应的源代码和头文件

技术分享图片

1.2. 定义数据结构类型到头文件:stu_info.h

    1.2.1 学生结构体的成员:"name", "age", "tel", "height", "weight", "addr" 
    1.2.2 数据结构体的成员:struct STU stu[MAX];int num; // num:用来表示有多少个记录
    1.2.3 定义一个枚举变量:用来存储选项的值:enum OPTIONS { EXIT, ADD, DELETE, MODIFY, SEARCH, SHOW, ORDER  };
    1.2.4 函数的声明:。。。。

1.3 创建一个测试源代码文件:test.c,用于测试

里面包含一个main函数和所需要的的头文件

1.4 创建所用到的函数定义的源文件:stu_info.c

1.5 功能

    (1)增、删、改、查、展示、排序(按照不同字段进行排序)
    (2)保存结果
    (3)再次运行时,会将保存的数据读入到数据中

1.6 用到的知识难点:

    (1)数据类型:结构体和枚举变量
    (2)函数参数:指针变量作为函数参数
    (3)指针类型:指针数组(如成员列表)
    (4)函数指针数组:void (*optp[7])(struct DATA*) = { save, add, del, modify, search, show, order }; 
    (5)回调函数:在进行排序时,如:self_qsort(data->stu, data->num, LEN, sortp[ret]);

第二:各个源文件的代码清单

2.1 主函数|测试函数:test.c

#define _CRT_SECURE_NO_WARNINGS 1

#pragma once
#include "stu_info.h"

int main()
{
    struct DATA data;
    read_data(&data);
    int input;
    // 通过函数指针和回调函数的方式进行实现
    void (*optp[7])(struct DATA*) = { save, add, del, modify, search, show, order }; 
    do
    {
        menu();
        scanf("%d", &input);
        if (-1 < input && input < 7)
        {
            optp[input](&data);
        }
        else
        {
            printf("选择错误!\n");
        }

    } while (input);
    // 通过switch语句的方式实现
    //do 
    //{
    //  menu();
    //  scanf("%d", &input);
    //  switch (input)
    //  {
    //  case ADD:
    //      add(&data); 
    //      break;
    //  case DELETE:
    //      del(&data);
    //      break;
    //  case MODIFY:
    //      modify(&data);
    //      break;
    //  case SEARCH:
    //      search(&data);
    //      break;      
    //  case SHOW:
    //      show(&data);
    //      break;
    //  case ORDER:
    //      order(&data);
    //      break;
    //  case EXIT:
    //      save(&data);
    //      printf("退出!");
    //      break;
    //  //  break;
    //  default:
    //      printf("Select Error!");
    //      break;
    //  }
    //} while (input);

    return 0;
}

2.2 头文件:stu_info.h

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#define FILENAME "datafile"
#define MAX 1000
#define NAME_MAX 30
#define TEL_MAX 12
#define ADDR_MAX 40
// 定义一个枚举类型用来存储选择项
enum OPTIONS { EXIT, ADD, DELETE, MODIFY, SEARCH, SHOW, ORDER  };

struct STU
{
    char name[NAME_MAX];
    int age;
    char tel[TEL_MAX];
    double height;
    double weight;
    char addr[ADDR_MAX];
};

#define stu_elenum  6
// char name ; int age; char tel; double height;double weight;chr addr
struct DATA
{
    struct STU stu[MAX];
    int num;
};

#define LEN sizeof(struct STU)
// 函数声明

// 菜单函数声明
void menu();

// 数据保存到磁盘文件
void save(const struct DATA* data);

// 读取磁盘文件中的数据保存到data结构体中
void read_data(struct DATA* data);

// 增加数据
void add(struct DATA* data);

// 展示数据
void show(const struct DATA* data);

// 删除数据
void del(struct DATA* data);

// 删除数据
void modify(struct DATA* data);

// 查找数据
void search(const struct DATA* data);

// 排序数据
void order(const struct DATA* data);

2.3 函数实现源文件:stu_info.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "stu_info.h"
char* stu_elelist[] = { "name", "age", "tel", "height", "weight", "addr" };

void menu()
{
    printf("\n\n\n");
    printf("\t\t|-------------------- Student grade system --------------------|\n");
    printf("\t\t|                     0. exit                                  |\n");
    printf("\t\t|                     1. add                                   |\n");
    printf("\t\t|                     2. delete                                |\n");
    printf("\t\t|                     3. modify                                |\n");
    printf("\t\t|                     4. search                                |\n");
    printf("\t\t|                     5. show                                  |\n");
    printf("\t\t|                     6. order                                 |\n");
    //printf("\t\t|                     7. show                                  |\n");
    printf("\t\t|--------------------------------------------------------------|\n");
    printf("\n\n\t\t\t\tplease select<0-7>:");
}

void save(const struct DATA* data)
{
    int i;
    FILE* fp;
    fp = fopen(FILENAME, "wb");
    if (NULL == fp)
    {
        printf("cannot open file: %s\n", FILENAME);
        exit(0);
    }
    else
    {
        for (i = 0; i < data->num; i++)
        {
            if (fwrite(&data->stu[i], LEN, 1, fp) != 1)
            {
                printf("file write error!\n");
            }
        }
        fclose(fp);
    }
}

void read_data(struct DATA* data)
{
    assert(data != NULL);
    FILE* fp;
    int i = 0;
    fp = fopen(FILENAME, "rb");
    if (NULL == fp)
    {
        printf("当前系统没有数据\n");
        data->num = 0;
    }
    else
    {
        //printf("%d\n", feof(fp));
        data->num = 0;
        while (feof(fp) == 0)
        {
            if (fread(&data->stu[data->num], LEN, 1, fp) == 1)
            {
                data->num++;
            }

        }
        fclose(fp);
    }
}

void show(const struct DATA* data)
{
    int i;
    //char name; int age; char tel; double height; double weight; chr addr
    printf("%-30s\t%-4s\t%-12s\t%-6s\t%-6s\t%-40s\n", "name", "age", "tel", "height", "weight", "addr");
    for (i = 0; i < data->num; i++)
    {
        printf("%-30s\t%-4d\t%-12s\t%.2lf\t%.2lf\t%-40s\n",
            data->stu[i].name,
            data->stu[i].age,
            data->stu[i].tel,
            data->stu[i].height,
            data->stu[i].weight,
            data->stu[i].addr);
    }
}

static void show_by_name(const struct DATA* data, int pos)
{
    //char name; int age; char tel; double height; double weight; chr addr
    printf("%-30s\t%-4s\t%-12s\t%-6s\t%-6s\t%-40s\n", "name", "age", "tel", "height", "weight", "addr");

    printf("%-30s\t%-4d\t%-12s\t%.2lf\t%.2lf\t%-40s\n",
        data->stu[pos].name,
        data->stu[pos].age,
        data->stu[pos].tel,
        data->stu[pos].height,
        data->stu[pos].weight,
        data->stu[pos].addr);
}

// find:return pos in data->stu
// not find: return -1
static int find_data_by_name(const struct DATA* data, const char* name)
{
    assert(data != NULL);
    int i;
    for (i = 0; i < data->num; i++)
    {
        if (strcmp(name, data->stu[i].name) == 0)
        {
            return i;
        }
    }
    return -1;
}

static int find_name(const struct DATA* data, char* opty)
{
    char name[NAME_MAX] = { 0 };
    int pos = 0;
    char choose = 0;
    do
    {
        printf("please input the %s student‘s name:", opty);
        scanf("%s", name);
        pos = find_data_by_name(data, name);
        if (-1 == pos)
        {
            printf("The student of %s not in the student information system.", name);
            printf("Whether continue %s student record<y/n>:", opty);
            getchar();
            choose = getchar();
        }
        else
        {
            return pos;
        }
    } while (choose == ‘y‘ || choose == ‘Y‘);
    return -1;
}

int sort_stu_by_name(const void* elem1, const void* elem2)
{
    return strcmp(((struct STU*)elem1)->name, ((struct STU*)elem2)->name); 
}

int sort_stu_by_age(const void* elem1, const void* elem2)
{
    return ((struct STU*)elem1)->age - ((struct STU*)elem2)->age; 
}

int sort_stu_by_tel(const void* elem1, const void* elem2)
{
    return strcmp(((struct STU*)elem1)->tel, ((struct STU*)elem2)->tel);
}

int sort_stu_by_height(const void* elem1, const void* elem2)
{
    if (((struct STU*)elem1)->height - ((struct STU*)elem2)->height > 1e-6)
        return 1;
    else if (((struct STU*)elem1)->height - ((struct STU*)elem2)->height < -1e-6)
        return -1;
    else
        return 0;
}

int sort_stu_by_weight(const void* elem1, const void* elem2)
{
    if (((struct STU*)elem1)->weight - ((struct STU*)elem2)->weight > 1e-6)
        return 1;
    else if (((struct STU*)elem1)->weight - ((struct STU*)elem2)->weight < -1e-6)
        return -1;
    else
        return 0;
}

int sort_stu_by_addr(const void* elem1, const void* elem2)
{
    return strcmp(((struct STU*)elem1)->addr, ((struct STU*)elem2)->addr);
}

void self_swap(char* buf1, char* buf2, int width)
{
    int i;
    char tmp;
    for (i = 0; i < width; i++)
    {
        tmp = *buf1;
        *buf1 = *buf2;
        *buf2 = tmp;
        buf1++;
        buf2++; 
    }
}

void self_qsort(void* base, int num, int width, int (*pfunc)(const void* elem1, const void* elem2))
{
    int i, j;
    int flags;
    for (i = 0; i < num - 1; i++)
    {
        flags = 1;
        for (j = 0; j < num - 1 - i; j++)
        {
            if (pfunc((char*)base + j * width, (char*)base + (j + 1) * width) > 0)
            {
                flags = 0;
                self_swap((char*)base + j * width, (char*)base + (j + 1) * width, width);
            }

        }
        if (1 == flags)
        {
            break;
        }
    }
}

void add(struct DATA* data)
{
    //char name; int age; char tel; double height; double weight; chr addr
    char choose;
    char name[NAME_MAX] = { 0 };
    int dup = -1;
    do
    {
        int num = data->num;
        printf("input name:");
        do
        {
            scanf("%s", name);
            dup = find_data_by_name(data, name);
            if (-1 == dup)
            {
                strcpy(data->stu[num].name, name); 
                break;
            }
            else
            {
                printf("The name of you input %s have existed, please renew input:", name);
            }
        } while (-1 != dup);

        //scanf("%s", data->stu[num].name);
        printf("input age:");
        scanf("%d", &data->stu[num].age);
        printf("input tel:");
        scanf("%s", data->stu[num].tel);
        printf("input height:");
        scanf("%lf", &data->stu[num].height);
        printf("input weight:");
        scanf("%lf", &data->stu[num].weight);
        printf("input addr:");
        scanf("%s", data->stu[num].addr);
        data->num++;
        printf("whether continue add student?<y/n>");
        //scanf("%s", choose);
        getchar();
        choose = getchar();
    } while (‘y‘ == choose || ‘Y‘ == choose);
}

void del(struct DATA* data)
{
    int pos = find_name(data, "delete");
    int i;

    if (-1 != pos)
    {
        char* name = data->stu[pos].name;
        printf("The delete student‘s information:\n");
        show_by_name(data, pos);
        for (i = pos; i < data->num - 1; i++)
        {
            data->stu[i] = data->stu[i + 1];
        }
        printf("Delete Finish: %s\n", name);
        data->num--;
    }
}

void modify(struct DATA* data)
{
    int pos = find_name(data, "modify");
    if (-1 != pos)
    {
        printf("The modify student‘s information:\n");
        show_by_name(data, pos);
        //printf("modify name:");
        //scanf("%s", data->stu[num].name);
        printf("modify age:");
        scanf("%d", &data->stu[pos].age);
        printf("modify tel:");
        scanf("%s", data->stu[pos].tel);
        printf("modify height:");
        scanf("%lf", &data->stu[pos].height);
        printf("modify weight:");
        scanf("%lf", &data->stu[pos].weight);
        printf("modify addr:");
        scanf("%s", data->stu[pos].addr);
        printf("modify success!\n");
        show_by_name(data, pos);
    }
}

void search(const struct DATA* data)
{
    int pos = find_name(data, "search");
    if (-1 != pos)
    {
        printf("search success!\n");
        show_by_name(data, pos);
    }
}

void order(const struct DATA* data)
{
    char choose[10];
    char* info = "sort by: name | age | tel | height | weight | addr, please choose : ";
    int ret = -1;
    int i;
    do
    {
        printf("%s", info);
        scanf("%s", choose);
        for (i = 0; i < stu_elenum; i++)
        {
            if (strcmp(choose, stu_elelist[i]) == 0)
            {
                ret = i;
                break;
            }
        }
    } while (-1 == ret);
    int (*sortp[stu_elenum])(const void*, const void*) = { sort_stu_by_name ,sort_stu_by_age, sort_stu_by_tel, sort_stu_by_height, sort_stu_by_weight, sort_stu_by_addr };
    self_qsort(data->stu, data->num, LEN, sortp[ret]);
}

第三:功能展示

部分功能展示:

3.1 菜单展示:

技术分享图片

3.2 数据展示:

技术分享图片

3.3 修改展示:

技术分享图片

3.4 排序展示:

技术分享图片
技术分享图片

通讯录的实现

原文:https://blog.51cto.com/u_15132389/2698903

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!