前言

每一个项目文件的功能说明

  • 打印基本菜单
  • 1.创建一个适合存放联系人信息的结构体和通讯录结构体
  • 2.初始化通讯录(加载上次的联系人,检查容量是否充足)

枚举常量内部内容

(1)增加联系人信息

(2)删除某个联系人信息

(3)查找联系人信息

(4)修改联系人信息

(5)展示联系人信息

(6)排序联系人信息(可以按照姓名,年龄,性别,电话,住址的等种类进行排序)

(7)清空通讯录

(8)保存当前录入的联系人信息

  • 所有函数的声明
  • 所有头文件
  • 完整代码
  • 文末:小编想说的话

前言

对于一个通讯录管理系统来说,较为重要的是清楚具体需要什么功能以及每一块功能的实现。

下面,实现一个通讯录,该通讯录能够进行联系人的添加,删除,查找,修改,展示,排序,保存,销毁,等功能。

我们知道,一个联系人有以下基本信息:联系人姓名,年龄,性别,电话,住址等。

所以下面来实现功能时,按照每一个功能逐一实现即可。

每一个项目文件的说明

该通讯录包含三个项目文件:
Contact.c文件
Contact.h文件
test.c文件

Contact.c文件是用来实现每个区域的功能。
Contact.h文件是用来声明函数,包含头文件的。
test.c文件是用来测试代码的(建议封装完一个函数,写完一个函数后就测试代码)

打印基本菜单,以供用户选择。

实现菜单较为简单,列出功能,共用户选择即可。

void menu(void)
{printf("*******************************\n");printf("******1.Add     2.Del    ******\n");printf("******3.Search  4.Modify ******\n");printf("******5.Show    6.Sort   ******\n");printf("******7.Clean   8.Save   ******\n");printf("******0.Exit             ******\n");printf("*******************************\n");}

1.创建一个适合存放联系人信息的结构体

上面讲到,联系人的信息有姓名,年龄,性别,电话,地址等


#define MAX 100
#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 12
#define ADDR_MAX 30
#define CAPACITY_SIZE 3//个人信息
typedef struct PeoInfo
{char name[NAME_MAX];int age;char sex[SEX_MAX];char tele[TELE_MAX];char addr[ADDR_MAX];
}PeoInfo;

基本联系人信息如上。

然而,这只是一个人的信息,一个通讯录有成百上千人,我们需要一块空间来存放联系人的信息,这就需要到一个结构体数组来存放每一个结构体联系人的信息,如下图:

又有一个问题了,当存放了第一个人的信息后,怎么找到第二个人的空间来存放?第三个人呢?

由此可以联想到,需要用到一个存储下标的结构体变量,每存储一个人的信息,该下标变量就++。

我们在一开始申请空间的时候,不适宜申请太多空间,申请多少空间,就用一个变量来记录,叫做capacity(容量),也就是结构体的申请的空间大小。

所以可以创建一个大空间存放每个人的信息,该空间也是一个结构体,包含一个数组和存储下标的变量和一个结构体的容量(能容纳多少个联系人)。

//整个通讯录信息
typedef struct Contact
{PeoInfo *data;int sz;int capacity;
}Contact;

2.初始化通讯录(加载上次的联系人,检查容量是否充足)

在初始化通讯录时,我们可以分装一个函数,专门实现该功能。

我们在写入联系人信息时,该信息会保存到本地的磁盘中,当我们再次进入通讯录时,应该加载上一次存放好的联系人的信息,防止用户重复存放等。
所以应该也需要封装一个加载信息的函数:

void LoadContact(Contact* ps)
{assert(ps);FILE* pfread = fopen("Contact.txt", "rb");//二进制形式读取PeoInfo tmp = { 0 };//把读取的联系人先放着,先判断容量够不够,再放进data里if (pfread == NULL){printf("LoadContact:%s\n", strerror(errno));}else{while (fread(&tmp, sizeof(PeoInfo), 1, pfread)){CheckCapacity(ps);//判断容量够不够ps->data[ps->sz] = tmp;ps->sz++;}}fclose(pfread);pfread = NULL;
}

初始化完通讯录后,就加载上一次的联系人信息出来。由于我们在进入通讯录时,申请的空间不多,有可能在本地磁盘中存储的联系人信息有多个,我们申请的空间只要少量,所以需要检查容量是否充足,如果容量不足,则需要再次申请空间。

//检查容量
void CheckCapacity(Contact* ps)
{assert(ps);if (ps->sz == ps->capacity){//扩容PeoInfo* ptr = realloc(ps->data, sizeof(PeoInfo) * (2 + ps->capacity));//一次扩容两个if (ptr == NULL){printf("%s\n", strerror(errno));printf("增容失败\n");}else{ps->data = ptr;ps->capacity += 2;printf("增容成功\n");}}
}

用上面的函数来检查容量。

void InitContact(Contact* ps)
{assert(ps);ps->data =(PeoInfo*)malloc(sizeof(PeoInfo) * CAPACITY_SIZE);if (ps->data == NULL){printf("%s\n", strerror(errno));}ps->capacity = CAPACITY_SIZE;ps->sz = 0;
}

初始化完通讯录之后,就可以开始逐一实现每个函数的功能了。

枚举常量内部内容:

对于枚举来说,其成员的排序是从0开始的,即第一个成员的序号是0,第二个成员的序号是1…

enum
{Exit,//0Add,//1Del,//2Search,//3Modify,//4Show,//5Sort,//6Clean,//7Save//8
};

(1)增加联系人信息

再增加联系人之前,需要检查当前的容量是否足够,如果不够,也是一样需要增容。

增加联系人的信息,就需要输入姓名,年龄,性别,电话,住址等。
并且每次增加完之后,指向联系人的下标的变量就需要++,向前走。

void AddContact(Contact* ps)
{assert(ps);CheckCapacity(ps);检查容量是否充足printf("请输入姓名:>\n");scanf("%s", ps->data[ps->sz].name);printf("请输入年龄:>\n");scanf("%d", &ps->data[ps->sz].age);printf("请输入性别:>\n");scanf("%s", ps->data[ps->sz].sex);printf("请输入电话:>\n");scanf("%s", ps->data[ps->sz].tele);printf("请输入住址:>\n");scanf("%s", ps->data[ps->sz].addr);ps->sz++;printf("添加成功\n");
}

(2)删除联系人信息

实现代码之前,先想想,删除一个联系人,是不是要先找到该联系人?不然怎么删除呢?
而找该联系人,就是第三个功能:查找联系人。
而第四个功能:删除联系人,同理,必须先找到想修改的联系人的信息,才能修改。
所以,这三个功能都有相同点:先找到目标联系人
封装一个函数来实现:

static int FindByName(const Contact* ps)
{assert(ps);char name[NAME_MAX] = { 0 };scanf("%s", name);for (int i = 0; i < ps->sz; i++){if (strcmp(ps->data[i].name, name) == 0){return i;}}return -1;
}

以名字来查找。

有了这个函数,就可以删除目标联系人了。

所谓的删除,不过就是往前覆盖,进行下标再- -

void DelContact(Contact* ps)
{assert(ps);printf("请输入要删除的人的名字:>\n");int pos = FindByName(ps);if (pos == -1){printf("要删除的人不存在\n");return;}//删除也就是向前覆盖即可for (int i = pos; i < ps->sz - 1; i++){ps->data[i] = ps->data[i + 1];}ps->sz--;printf("删除成功\n");
}

(3)查找联系人信息

查找联系人信息,然后打印出来。

void SearchContact(const Contact* ps)
{assert(ps);printf("请输入要查找的人的名字:>\n");int pos = FindByName(ps);if (pos == -1){printf("要查找的人不存在\n");return;}printf("%-20s\t%-4s\t%-5s\t%-12s\t%-30s\n", "姓名", "年龄", "性别", "电话", "住址");printf("%-20s\t%-4d\t%-5s\t%-12s\t%-30s\n", ps->data[pos].name,ps->data[pos].age,ps->data[pos].sex,ps->data[pos].tele,ps->data[pos].addr);}

(4)修改联系人信息

void ModifyContact(Contact* ps)
{assert(ps);printf("请输入要修改的人的名字:>\n");int pos = FindByName(ps);if (pos == -1){printf("要修改的人不存在\n");return;}printf("请输入姓名:>\n");scanf("%s", ps->data[pos].name);printf("请输入年龄:>\n");scanf("%d", &ps->data[pos].age);printf("请输入性别:>\n");scanf("%s", ps->data[pos].sex);printf("请输入电话:>\n");scanf("%s", ps->data[pos].tele);printf("请输入住址:>\n");scanf("%s", ps->data[pos].addr);printf("修改成功\n");
}

(5)展示联系人信息

void ShowContact(const Contact* ps)
{assert(ps);if (ps->sz == 0){printf("通讯录为空\n");return;}printf("%-20s\t%-4s\t%-5s\t%-12s\t%-30s\n", "姓名","年龄","性别", "电话","住址");for (int i = 0; i < ps->sz; i++){printf("%-20s\t%-4d\t%-5s\t%-12s\t%-30s\n", ps->data[i].name, ps->data[i].age, ps->data[i].sex,ps->data[i].tele, ps->data[i].addr);}}

(6)对联系人信息进行排序

提供的排序种类有:姓名,年龄,性别,电话,住址

int cmp_name(const void* e1, const void* e2)
{return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}int cmp_age(const void* e1, const void* e2)
{return ((PeoInfo*)e1)->age - ((PeoInfo*)e2)->age ;
}int cmp_sex(const void* e1, const void* e2)
{return strcmp(((PeoInfo*)e1)->sex, ((PeoInfo*)e2)->sex);
}int cmp_tele(const void* e1, const void* e2)
{return strcmp(((PeoInfo*)e1)->tele, ((PeoInfo*)e2)->tele);
}int cmp_addr(const void* e1, const void* e2)
{return strcmp(((PeoInfo*)e1)->addr, ((PeoInfo*)e2)->addr);
}void SortContact(Contact* ps)
{assert(ps);char tmp[5] = { 0 };printf("请输入要排序的种类:>\n");printf("(姓名,年龄,性别,电话,住址)\n");scanf("%s", tmp);char* arr[5] = { "姓名","年龄","性别","电话","住址" };if (strcmp(arr[0], tmp) == 0){//起始地址,排序个数,每个元素大小,比较方法qsort(ps->data,ps->sz,sizeof(ps->data[0]),cmp_name);}if (strcmp(arr[1], tmp) == 0){//起始地址,排序个数,每个元素大小,比较方法qsort(ps->data, ps->sz, sizeof(ps->data[0]), cmp_age);}if (strcmp(arr[2], tmp) == 0){//起始地址,排序个数,每个元素大小,比较方法qsort(ps->data, ps->sz, sizeof(ps->data[0]), cmp_sex);}if (strcmp(arr[3], tmp) == 0){//起始地址,排序个数,每个元素大小,比较方法qsort(ps->data, ps->sz, sizeof(ps->data[0]), cmp_tele);}if (strcmp(arr[4], tmp) == 0){//起始地址,排序个数,每个元素大小,比较方法qsort(ps->data, ps->sz, sizeof(ps->data[0]), cmp_addr);}printf("排序成功\n");}
void CleanContact(Contact* ps)
{if (ps->sz == 0){printf("通讯录已为空,无需清除\n");return;}memset(ps->data, 0, ps->sz);ps->sz = 0;printf("清除成功\n");
}

(7)清空联系人列表

void CleanContact(Contact* ps)
{if (ps->sz == 0){printf("通讯录已为空,无需清除\n");return;}memset(ps->data, 0, ps->sz);ps->sz = 0;printf("清除成功\n");
}

(8)保存当前的联系人信息到本地磁盘中

保存信息也就是写入文件。

void SaveContact(Contact* ps)
{assert(ps);size_t count = 0;if (ps->sz == 0){printf("无要保存的联系人\n");return;}FILE* pfwrite = fopen("Contact.txt", "wb");//以二进制形式写入if (pfwrite == NULL){printf("SaveContact:%s\n", strerror(errno));}for (int i = 0; i < ps->sz; i++){count = fwrite(&(ps->data[i]), sizeof(ps->data[0]), 1, pfwrite);//size_t fwrite(const void* buffer, size_t size, size_t count, FILE * stream);}if (ps->sz == (int)count){printf("所有联系人全部保存成功\n");}else{printf("保存了%zd个联系人", count);}fclose(pfwrite);pfwrite = NULL;
}

所有函数的声明

//初始化通讯录
void InitContact(Contact* ps);
//增加联系人信息
void AddContact(Contact *ps);
//展示联系人信息
void ShowContact(const Contact*ps);
//删除联系人信息
void DelContact(Contact* ps);
//搜索联系人信息
void SearchContact(const Contact *ps);
//修改联系人信息
void ModifyContact(Contact *ps);
//对联系人进行排序
void SortContact(Contact* ps);
//清空联系人
void CleanContact(Contact*ps);
//退出时销毁通讯录
void DestroyContact(Contact *ps);
//保存通讯录信息
void SaveContact(Contact* ps);

头文件如下:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
#include<errno.h>

完整代码如下:

Contact.h项目文件

#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
#include<errno.h>#define MAX 100
#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 12
#define ADDR_MAX 30
#define CAPACITY_SIZE 3//个人信息
typedef struct PeoInfo
{char name[NAME_MAX];int age;char sex[SEX_MAX];char tele[TELE_MAX];char addr[ADDR_MAX];
}PeoInfo;//整个通讯录信息
typedef struct Contact
{PeoInfo *data;int sz;int capacity;
}Contact;//初始化通讯录
void InitContact(Contact* ps);
//增加联系人信息
void AddContact(Contact *ps);
//展示联系人信息
void ShowContact(const Contact*ps);
//删除联系人信息
void DelContact(Contact* ps);
//搜索联系人信息
void SearchContact(const Contact *ps);
//修改联系人信息
void ModifyContact(Contact *ps);
//对联系人进行排序
void SortContact(Contact* ps);
//清空联系人
void CleanContact(Contact*ps);
//退出时销毁通讯录
void DestroyContact(Contact *ps);
//保存通讯录信息
void SaveContact(Contact* ps);enum
{Exit,//0Add,//1Del,//2Search,//3Modify,//4Show,//5Sort,//6Clean,//7Save//8
};

Contact.c项目文件如下:

#include"Contact.h"//检查容量
void CheckCapacity(Contact* ps)
{assert(ps);if (ps->sz == ps->capacity){//扩容PeoInfo* ptr = realloc(ps->data, sizeof(PeoInfo) * (2 + ps->capacity));//一次扩容两个if (ptr == NULL){printf("%s\n", strerror(errno));printf("增容失败\n");}else{ps->data = ptr;ps->capacity += 2;printf("增容成功\n");}}
}//加载联系人信息
void LoadContact(Contact* ps)
{assert(ps);FILE* pfread = fopen("Contact.txt", "rb");//二进制形式读取PeoInfo tmp = { 0 };//把读取的联系人先放着,先判断容量够不够,再放进data里if (pfread == NULL){printf("LoadContact:%s\n", strerror(errno));}else{//size_t fread( void *buffer, size_t size, size_t count, FILE *stream );while (fread(&tmp, sizeof(PeoInfo), 1, pfread)){CheckCapacity(ps);//判断容量够不够ps->data[ps->sz] = tmp;ps->sz++;}}fclose(pfread);pfread = NULL;}//初始化通讯录
void InitContact(Contact* ps)
{assert(ps);ps->data =(PeoInfo*)malloc(sizeof(PeoInfo) * CAPACITY_SIZE);if (ps->data == NULL){printf("%s\n", strerror(errno));}ps->capacity = CAPACITY_SIZE;ps->sz = 0;LoadContact(ps);//从上次保存的文件中加载联系人信息出来//memset(ps->data, 0, sizeof(ps->data));//ps->sz = 0;
}void AddContact(Contact* ps)
{assert(ps);CheckCapacity(ps);printf("请输入姓名:>\n");scanf("%s", ps->data[ps->sz].name);printf("请输入年龄:>\n");scanf("%d", &ps->data[ps->sz].age);printf("请输入性别:>\n");scanf("%s", ps->data[ps->sz].sex);printf("请输入电话:>\n");scanf("%s", ps->data[ps->sz].tele);printf("请输入住址:>\n");scanf("%s", ps->data[ps->sz].addr);ps->sz++;printf("添加成功\n");
}static int FindByName(const Contact* ps)
{assert(ps);char name[NAME_MAX] = { 0 };scanf("%s", name);for (int i = 0; i < ps->sz; i++){if (strcmp(ps->data[i].name, name) == 0){return i;}}return -1;
}void DelContact(Contact* ps)
{assert(ps);printf("请输入要删除的人的名字:>\n");int pos = FindByName(ps);if (pos == -1){printf("要删除的人不存在\n");return;}//删除也就是向前覆盖即可for (int i = pos; i < ps->sz - 1; i++){ps->data[i] = ps->data[i + 1];}ps->sz--;printf("删除成功\n");
}void SearchContact(const Contact* ps)
{assert(ps);printf("请输入要查找的人的名字:>\n");int pos = FindByName(ps);if (pos == -1){printf("要查找的人不存在\n");return;}printf("%-20s\t%-4s\t%-5s\t%-12s\t%-30s\n", "姓名", "年龄", "性别", "电话", "住址");printf("%-20s\t%-4d\t%-5s\t%-12s\t%-30s\n", ps->data[pos].name,ps->data[pos].age,ps->data[pos].sex,ps->data[pos].tele,ps->data[pos].addr);}void ModifyContact(Contact* ps)
{assert(ps);printf("请输入要修改的人的名字:>\n");int pos = FindByName(ps);if (pos == -1){printf("要修改的人不存在\n");return;}printf("请输入姓名:>\n");scanf("%s", ps->data[pos].name);printf("请输入年龄:>\n");scanf("%d", &ps->data[pos].age);printf("请输入性别:>\n");scanf("%s", ps->data[pos].sex);printf("请输入电话:>\n");scanf("%s", ps->data[pos].tele);printf("请输入住址:>\n");scanf("%s", ps->data[pos].addr);printf("修改成功\n");
}void ShowContact(const Contact* ps)
{assert(ps);if (ps->sz == 0){printf("通讯录为空\n");return;}printf("%-20s\t%-4s\t%-5s\t%-12s\t%-30s\n", "姓名","年龄","性别", "电话","住址");for (int i = 0; i < ps->sz; i++){printf("%-20s\t%-4d\t%-5s\t%-12s\t%-30s\n", ps->data[i].name, ps->data[i].age, ps->data[i].sex,ps->data[i].tele, ps->data[i].addr);}}int cmp_name(const void* e1, const void* e2)
{return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}int cmp_age(const void* e1, const void* e2)
{return ((PeoInfo*)e1)->age - ((PeoInfo*)e2)->age ;
}int cmp_sex(const void* e1, const void* e2)
{return strcmp(((PeoInfo*)e1)->sex, ((PeoInfo*)e2)->sex);
}int cmp_tele(const void* e1, const void* e2)
{return strcmp(((PeoInfo*)e1)->tele, ((PeoInfo*)e2)->tele);
}int cmp_addr(const void* e1, const void* e2)
{return strcmp(((PeoInfo*)e1)->addr, ((PeoInfo*)e2)->addr);
}void SortContact(Contact* ps)
{assert(ps);char tmp[5] = { 0 };printf("请输入要排序的种类:>\n");printf("(姓名,年龄,性别,电话,住址)\n");scanf("%s", tmp);char* arr[5] = { "姓名","年龄","性别","电话","住址" };if (strcmp(arr[0], tmp) == 0){//起始地址,排序个数,每个元素大小,比较方法qsort(ps->data,ps->sz,sizeof(ps->data[0]),cmp_name);}if (strcmp(arr[1], tmp) == 0){//起始地址,排序个数,每个元素大小,比较方法qsort(ps->data, ps->sz, sizeof(ps->data[0]), cmp_age);}if (strcmp(arr[2], tmp) == 0){//起始地址,排序个数,每个元素大小,比较方法qsort(ps->data, ps->sz, sizeof(ps->data[0]), cmp_sex);}if (strcmp(arr[3], tmp) == 0){//起始地址,排序个数,每个元素大小,比较方法qsort(ps->data, ps->sz, sizeof(ps->data[0]), cmp_tele);}if (strcmp(arr[4], tmp) == 0){//起始地址,排序个数,每个元素大小,比较方法qsort(ps->data, ps->sz, sizeof(ps->data[0]), cmp_addr);}printf("排序成功\n");}void CleanContact(Contact* ps)
{if (ps->sz == 0){printf("通讯录已为空,无需清除\n");return;}memset(ps->data, 0, ps->sz);ps->sz = 0;printf("清除成功\n");
} void DestroyContact(Contact* ps)
{free(ps->data);ps->data = NULL;printf("销毁成功\n");
}void SaveContact(Contact* ps)
{assert(ps);size_t count = 0;if (ps->sz == 0){printf("无要保存的联系人\n");return;}FILE* pfwrite = fopen("Contact.txt", "wb");//以二进制形式写入if (pfwrite == NULL){printf("SaveContact:%s\n", strerror(errno));}for (int i = 0; i < ps->sz; i++){count = fwrite(&(ps->data[i]), sizeof(ps->data[0]), 1, pfwrite);//size_t fwrite(const void* buffer, size_t size, size_t count, FILE * stream);}if (ps->sz == (int)count){printf("所有联系人全部保存成功\n");}else{printf("保存了%zd个联系人", count);}fclose(pfwrite);pfwrite = NULL;
}

test.c项目文件如下:

#include"Contact.h"void menu(void)
{printf("*******************************\n");printf("******1.Add     2.Del    ******\n");printf("******3.Search  4.Modify ******\n");printf("******5.Show    6.Sort   ******\n");printf("******7.Clean   8.Save   ******\n");printf("******0.Exit             ******\n");printf("*******************************\n");}int main()
{int input = 0;//创建通讯录Contact con;//初始化通讯录InitContact(&con);do{menu();printf("请选择:>\n");scanf("%d", &input);switch (input){case Exit:SaveContact(&con);//退出时自动保存printf("在您退出通讯录时,已自动为您保存\n");DestroyContact(&con);//退出时销毁通讯录printf("退出通讯录\n");break;case Add:AddContact(&con);break;case Del:DelContact(&con);break;case Search:SearchContact(&con);break;case Modify:ModifyContact(&con);break;case Show:ShowContact(&con);break;case Sort:SortContact(&con);break;case Clean:CleanContact(&con);break;case Save:SaveContact(&con);break;default:printf("选择错误,请重新选择:>\n");break;}} while (input);return 0;
}

小编想说的话

在实现通讯录的功能时,还有诸多不够完善的地方,以上通讯录系统是小编花好些时间一点点封装出来的,如有bug,欢迎在评论区指正!谢谢呀。

如果对你有帮助的话,请关注我呀!

【基于动态内存+文件操作】通讯录管理系统相关推荐

  1. 《小猫猫大课堂》三轮5——动态内存管理(通讯录动态内存化)

    宝子,你不点个赞吗?不评个论吗?不收个藏吗? 最后的最后,关注我,关注我,关注我,你会看到更多有趣的博客哦!!! 喵喵喵,你对我真的很重要. 目录 前言 动态内存产生的原因 动态内存函数 malloc ...

  2. C语言文件操作+通讯录实现文件操作

    文章目录 前言 一.为什么使用文件 二.什么是文件 三.文件的打开和关闭 四.文件的顺序读写 五.文件的随机读写 六.文本文件和二进制文件 七.文件读取结束的判定 八.文件缓冲区 前言 电脑文件,也可 ...

  3. 【C 语言】文件操作 ( 学生管理系统 | 插入数据 | 查询数据 | 删除数据 )

    文章目录 一.学生管理系统 1.插入数据 2.查询数据 3.删除数据 二.完整代码 一.学生管理系统 实现一个简易学生管理系统 , 验证文件操作 ; 1.插入数据 从命令行接收数据 , 放入结构体成员 ...

  4. 【Android 逆向】Android 进程注入工具开发 ( 远程进程注入动态库文件操作 | 注入动态库 加载 业务动态库 | 业务动态库启动 | pthread_create 线程开发 )

    文章目录 前言 一.加载 libnattive.so 动态库 二. libnattive.so 动态库启动 三. pthread_create 线程开发 四. 线程执行函数 前言 libbridge. ...

  5. 【Android 逆向】Android 进程注入工具开发 ( 远程进程 注入动态库 文件操作 | Android 进程读取文件所需的权限 | fopen 打开文件标志位 | 验证文件权限 )

    文章目录 前言 一.Android 进程读取文件所需的权限 二.fopen 打开文件标志位 三.验证文件权限 前言 一.Android 进程读取文件所需的权限 通过 注入工具 , 将 libbridg ...

  6. 动态内存分配版本 通讯录的实现 (C语言)

    之前写过一个 件简单的通讯录,含有 增加.删除.修改.查找.排序.显示功能,现做进一步改进,修改成动态内存分配的版本. 代码如下:(详见注释) #include <stdio.h> #in ...

  7. 【C 语言】文件操作 ( 学生管理系统 | 命令行接收数据填充结构体 | 结构体写出到文件中 | 查询文件中的结构体数据 )

    文章目录 一.学生管理系统 二.代码示例 一.学生管理系统 前两篇博客 [C 语言]文件操作 ( 将结构体写出到文件中并读取结构体数据 | 将结构体数组写出到文件中并读取结构体数组数据 ) [C 语言 ...

  8. SylixOS动态内存分配操作

    SylixOS 系统内存管理分为两大类: 内存堆管理和虚拟内存管理. 对用户来说内存堆管理的分配最小单位为 1 个字节, 虚拟内存管理分配最小单位为 1 个页面(通常为 4096 字节) 内核部分 操 ...

  9. 基于Python的文件操作之第1课读文件

    学习目标 掌握基于python对文件相关操作 每种格式包含很多相关操作,学习只要掌握知识点的用法,参考笔记可以实现相关的练习即可,不必背会,在企业开发过程中边搜实现. 学习内容 了解python函数和 ...

最新文章

  1. java8新特新:接口流-Stream()接口和所有方法(map,foreach,filter,count,distinct,limit,collect,skip,sorted)
  2. client中周期性边界_「微评」增加艺术品在投资组合中的比例 推进国家艺术软实力...
  3. 一种父线程阻塞等待子线程的有效方法
  4. LeetCode 422. 有效的单词方块
  5. MySQL 限制查询结果的记录数
  6. 练习题︱streamlit + opencv/YOLOv3 快速构建自己的图像目标检测demo网页
  7. 如何解决 MacBook Pro Touch ID不起作用?
  8. 极客大学架构师训练营 大数据 GFS、MapReduce、BigTable,Hadoop HDFS Yarn HiveQL 第12次作业
  9. sqlyog注册码激活
  10. win2008虚拟化服务器配置,Win2008虚拟化实战之创建虚拟机
  11. 手机内存文件夹html,手机内存越用越小?删除这6个英文文件夹,瞬间释放20G
  12. Java去掉红色印章,基于RGB和HSV实现红色公章删除
  13. android切换高德导航,Android调起高德地图
  14. Android Studio App开发中使用录音机、MediaRecorder录制音频和MediaPlayer播放音频讲解及实战(附源码)
  15. 深入理解Linux启动过程 0号进程,1号进程
  16. POJ - 1849 Two(树的直径)
  17. 半导体器件基础07:三极管基础(3)
  18. PS2 玩USB ISO游戏的方法
  19. android开发 自我优势_6年Android开发程序员教你如何写简历!看完别再问为何你只值5K...
  20. Putty配色方案更改

热门文章

  1. android 获取视频编码,Android视频编码
  2. iPhone 导入照片显示时间不是拍摄时间
  3. [翻译] 在 Overleaf 中使用参考文献
  4. STM32学习过程一
  5. android 重启自身app
  6. balsamiq mockups 注册
  7. 微信小程序——读取显示用户头像昵称
  8. Apollo星火计划学习笔记|L1 Apollo平台安装(2021年9月更新)
  9. 一本纯属个人的兴趣的书籍即将在未来面世
  10. 专访阿里巴巴元境王矛:打造研运一体化平台,去做开创性的事