当前位置:网站首页>[C language] implementation of three versions of address book small project (including source code)
[C language] implementation of three versions of address book small project (including source code)
2022-07-24 09:38:00 【Hua Qiujing】
Catalog
🧩 Change the structure definition
🧩 Change the initialization function
🧩 Change and add contact function
🧩 Destroy address book on exit
🧩3. dynamic + Document version
🧩 Function to save information
🧩 Check the full capacity function
🧩 Load data from file to memory
🧩 Please look forward to better works ~
Preface
learned C The basic grammar of language 、 Array 、 function 、 The pointer 、 Custom type 、 Dynamic memory allocation 、 I have mastered some knowledge such as document operation C Basics , At this time, writing small projects is a good way to consolidate , This article will share a wave of use C Language simple implementation of three versions of the address book applet ( The source code is at the end of the article ).
If you have not mastered the knowledge, you'd better learn it first and then read this article , Welcome readers to my C Language column reference .
Due to the limited level of the author , It's hard to avoid mistakes , Readers can take what they need .

🧩1. Static version
🧩 demand
1. Can be stored in the address book 1000 Personal information
2. Everyone's information includes : full name + Age + Gender + Telephone + Address
3. Add, delete, check and modify the information of the designated person
4. Can sort the address book information
5. You can print out the required information
6. Quit at any time
🧩 The basic structure
Use three files to realize , One is the file that runs the main function test.c, One is the file that stores the specific functions of the address book contact.c, The other is the corresponding header file contact.h.
Because you need to constantly refresh the status after each operation , So use do while loop .
Initialize the menu , Definition menu function ,1-6 Corresponding to addition, deletion, modification and sorting 、 Print ,0 Exit .
void menu()
{
printf("************************************************\n");
printf("************* 1.add 2.del ***********\n");
printf("************* 3.search 4.modify ***********\n");
printf("************* 5.sort 6.print ***********\n");
printf("************* 0.exit ***********\n");
printf("************************************************\n");
printf("************************************************\n");
}The next operation needs to be determined according to user input , use input Receive input value ,switch() Corresponding 7 In this case .
Defines an enumeration , If you just use case 1: It is not clear which operation corresponds to such statements , And using enumeration constants can be very clear input Which operation does the value of correspond to .
// Prevent forgetting the corresponding operation of options
enum Option
{
EXIT,
ADD,
DEL,
SEARCH,
MODIFY,
SORT,
PRINT
};
int main()
{
int input = 0;
do
{
menu();
printf(" Please select :>");
scanf_s("%d",&input);
switch (input)
{
case EXIT:
break;
case ADD:
break;
case DEL:
break;
case SEARCH:
break;
case MODIFY:
break;
case PRINT:
break;
case SORT:
break;
default:
break;
}
} while (input);
system("pause");
}To store information about multiple people , And everyone's information has these five attributes , But the corresponding values are different , So use structures to encapsulate variables , Many people use structure array .
Define constants with macros , Easy to modify .
Why use another layer of structure encapsulation ? To add a variable to record the number of contacts stored in the address book , Be similar to Indexes .
For structure type definitions , Because the two one. c All documents should use the corresponding structure , So put it in the header file contact.h in .
#define MAX_NAME 20
#define MAX_SEX 10
#define MAX_TELE 12
#define MAX_ADDR 30
#define MAX 1000
// Structure type definition -- Personal information
struct PeoInfo
{
char name[MAX_NAME];
char sex[MAX_SEX];
int age;
char tele[MAX_TELE];
char addr[MAX_ADDR];
};
// Address book structure
typedef struct Contact
{
struct PeoInfo data[MAX];// Store information
int size;// Record the number of valid messages in the current address book
}Contact;Then design functions according to functional requirements , Pass the structure address to each function ( More efficient ).
Each function definition is placed in contact.c, The statement is placed in contact.h.
🧩 Initialization function
Use memset The function initializes the entire structure to 0.
// Initialize address book
void InitContact(Contact*pc)
{
// Set all zeros
memset(pc, 0, sizeof(pc));
}
🧩 Add contact function
utilize size As index ,size That is, the number of contacts saved at present and the order of the next contacts to be stored , such as size == 5 The representative will now enter the information of the fifth person . Structure array data With size Subscript , After each person's information is added size++.
// Add contacts
void AddContact(Contact* pc)
{
// First, judge whether the address book is full
if (pc->size == MAX)
{
printf(" The address book is full , No more contacts can be added !\n");
return;// There is no return value, but it can be used to end the function
}
// Add a person's information
printf(" Please enter a name :>");
scanf("%s",pc->data[pc->size].name);
getchar();
printf(" Please enter age :>");
scanf("%d",&(pc->data[pc->size].age));
printf(" Please enter gender :>");
scanf("%s", pc->data[pc->size].sex);
getchar();
printf(" Please input the phone number :>");
scanf("%s", pc->data[pc->size].tele);
getchar();
printf(" Please enter the address :>");
scanf("%s", pc->data[pc->size].addr);
getchar();
pc->size++;// Indexes +1
printf(" Increase success !\n");
}🧩 Print function
In order to see how the information input effect of the previous function is , Let's write the print function first .
// Print contact information
void PrintContact(const Contact* pc)// Constant pointer anti modification , Only the printing operation does not need to change the original structure
{
int i;
printf("%-15s\t%-5s\t%-5s\t%-12s\t%-20s\n"," full name "," Age "," Gender "," Telephone "," Address ");
// Print all contact information
for (i = 0; i < pc->size; i++)
{
printf("%-15s\t%-5d\t%-5s\t%-12s\t%-20s\n", pc->data[i].name,
pc->data[i].age,
pc->data[i].sex,
pc->data[i].tele,
pc->data[i].addr);// In order to look comfortable
}
}🧩 Delete contact information
What is the premise of deletion ? Only the information already exists in the address book can be deleted , So at first, you need to judge whether the address book is empty .
We want to delete the selected contact , You should first find the location of the contact information , Then perform the delete operation .
So we should first write a function to find contacts according to the contact name information . Then pay attention to how to delete contacts , The method adopted here is to make the information of each person behind cover the information of the previous person , Until the last one covers the penultimate personal information , And then size Reduce 1 That is, the total number of storage -1, Originally, the information of the last person was blocked ( The data still exists , If you add contacts, you can overwrite them ).

// Find contacts ( By name , Used only in this source file )
static int FindByName(Contact* pc, char name[])
{
int i = 0;
for (i = 0; i < pc->size; i++)
{
// Using string comparison functions , by 0 Then we find , Returns the corresponding array subscript
if (strcmp(pc->data[i].name, name) == 0)
return i;
}
return -1;
}
// Delete Contact
void DelContact(Contact* pc)
{
char name[MAX_NAME];
// First, judge whether the address book is empty
if (pc->size == 0)
{
printf(" The address book is empty , Cannot delete (* ̄3 ̄)╭");
return;// End function
}
printf(" Please enter the name of the person to delete :>");
scanf("%s", name);
//1. Find contacts ( By name )
int pos = FindByName(pc, name);// Returns an array index
// Contact not found
if (pos == -1)
{
printf(" No one is found , Try another one !\n");
return;
}
//2. Delete Contact
int i = 0;
for (i = pos; i < pc->size - 1; i++)
{
// Put the subscript pos The following information moves forward
pc->data[i] = pc->data[i + 1];
}
// Total number of contacts -1, The original last contact information is equivalent to being blocked
pc->size--;
printf(" Delete successful !\n");
}
🧩 Find contact information
Find and print the information of the target contact , Here we use FindByName() Functions can be built directly on the basis of functions .
// Find contacts ( According to the name and print the information )
void SearchContact(Contact* pc)
{
char name[MAX_NAME];
printf(" Please enter the name of the contact you want to find :>");
scanf("%s",name);
getchar();
//1. Find contacts ( By name )
int pos = FindByName(pc, name);// Returns an array index
// Contact not found
if (pos == -1)
{
printf(" No one is found , Try another one !\n");
return;
}
else
{
//2. Print target contact information
printf("%-15s\t%-5s\t%-5s\t%-12s\t%-20s\n", " full name ", " Age ", " Gender ", " Telephone ", " Address ");
printf("%-15s\t%-5d\t%-5s\t%-12s\t%-20s\n", pc->data[pos].name,
pc->data[pos].age,
pc->data[pos].sex,
pc->data[pos].tele,
pc->data[pos].addr);
}
}🧩 Modify contact information
Modification is divided into single modification and all modifications , You need to find the contact person before modifying , You can call FindByName(), If found, print the information of the target first , Then choose single item or modify all , Defined here char modification[5] To receive the user's choice , Reuse strcmp() Compare one by one , When modifying size unchanged , Directly overwrite the original contact information at the specified location .
// Modify contact information
void ModifyContact(Contact* pc)
{
char name[MAX_NAME];
char modification[5];
printf(" Please enter the name of the contact to be modified :>");
scanf("%s", name);
getchar();
//1. Find contacts ( By name )
int pos = FindByName(pc, name);// Returns an array index
// Contact not found
if (pos == -1)
{
printf(" No one is found , Try another one !\n");
return;
}
else
{
//2. Print target contact information
printf("%-15s\t%-5s\t%-5s\t%-12s\t%-20s\n", " full name ", " Age ", " Gender ", " Telephone ", " Address ");
printf("%-15s\t%-5d\t%-5s\t%-12s\t%-20s\n", pc->data[pos].name,
pc->data[pos].age,
pc->data[pos].sex,
pc->data[pos].tele,
pc->data[pos].addr);
//3. Modify the information of the target contact
printf(" Input Chinese , Individual ( Such as name, etc ) Or all \n");
printf(" Please enter the option to modify :>");
scanf("%s",modification);
getchar();
// All modified
if (strcmp(modification, " All ") == 0)
{
printf(" Please enter a name :>");
scanf("%s", pc->data[pos].name);
getchar();
printf(" Please enter age :>");
scanf("%d", &(pc->data[pos].age));
printf(" Please enter gender :>");
scanf("%s", pc->data[pos].sex);
getchar();
printf(" Please input the phone number :>");
scanf("%s", pc->data[pos].tele);
getchar();
printf(" Please enter the address :>");
scanf("%s", pc->data[pos].addr);
getchar();
}
// Single item modification
if (strcmp(modification, " full name ") == 0)
{
printf(" Please enter a name :>");
scanf("%s", pc->data[pos].name);
getchar();
}
if (strcmp(modification, " Age ") == 0)
{
printf(" Please enter age :>");
scanf("%d", &(pc->data[pos].age));
}
if (strcmp(modification, " Gender ") == 0)
{
printf(" Please enter gender :>");
scanf("%s", pc->data[pos].sex);
getchar();
}
if (strcmp(modification, " Telephone ") == 0)
{
printf(" Please input the phone number :>");
scanf("%s", pc->data[pos].tele);
getchar();
}
if (strcmp(modification, " Address ") == 0)
{
printf(" Please enter the address :>");
scanf("%s", pc->data[pos].addr);
getchar();
}
printf(" Modification successful !\n");
}
}🧩 Sort contact information
After we save the contact information , What if you want to sort the contact information according to some standard ? have access to qsort function . Here we only sort by name .
static int CmpContactByName(const void* n1, const void* n2)
{
return strcmp(((PeoInfo *)n1)->name, ((PeoInfo*)n2)->name);
}
void SortContact(Contact* pc)
{
if (0 == pc->size)
{
printf(" The address book is empty , Unable to sort pinch ~\n");
return;
}
qsort(pc->data, pc->size, sizeof(PeoInfo), CmpContactByName);
printf(" Sort by name ...... Sort success !\n");
}🧩 Set clear screen
I don't know whether readers will feel uncomfortable reading all the text in the window because of printing all the time , Is there any way to clear the screen after each use ( Refresh the contents of the window ) Well ?
Consider using system commands cls To clear the screen , Need to include header file <stdlib.h>, Use system("cls").
But , If you clear the screen directly , Some printed information can't be seen , Can we do as we want , Only after pressing a certain key can the screen be cleared ? Tolerable , For example, press the space to clear the screen , use getch(VS Next is _getch) The function receives a character without echo or buffer , At this point, the program will wait for the user to type a value and pause , Enter the corresponding value before continuing , Then you can set a cycle , Only when the received character is a space, it will jump out of the loop to clear the screen , Otherwise, repeat the reception .
do
{
menu();
printf(" Please select a number :>");
scanf("%d",&input);
switch (input)
{
case EXIT:
printf(" Exit address book !");
break;
case ADD:
AddContact(&Con);
break;
case DEL:
DelContact(&Con);
break;
case SEARCH:
SearchContact(&Con);
break;
case MODIFY:
ModifyContact(&Con);
break;
case PRINT:
PrintContact(&Con);
break;
case SORT:
SortContact(&Con);
break;
default:
printf(" Wrong choice , Please reselect !");
break;
}
char ch;
do
{
printf(" Press the space to continue ...\n");
} while ((ch = _getch()) != ' ');
system("cls");
} while (input);Basically completed the requirements , This is the implementation of the static version of the address book .
🧩2. Dynamic version
🧩 New requirements :
1. The address book can be stored after initialization 3 Personal information .
2. Whenever the space is full , Automatically add 2 Personal information corresponds to memory space .
🧩 Change the structure definition

stay contact.h in
// Address book structure -- Dynamic version
typedef struct Contact
{
struct PeoInfo * data;// Point to the space of dynamic application , Used to store information , It can be directly used as an array
int size;// Record the number of valid messages in the current address book
int capacity;// Record the maximum capacity of contacts in the current address book
}Contact;🧩 Change the initialization function
stay contact.h in
#define DEFAULT_SIZE 3// The initial default size of the address book
#define INC_SIZE 2// Each expansion increment By the way, rename the name of the structure type
// Structure type definition -- Personal information
typedef struct PeoInfo
{
char name[MAX_NAME];
char sex[MAX_SEX];
int age;
char tele[MAX_TELE];
char addr[MAX_ADDR];
}PeoInfo;Then change the initialization function , stay contact.c in
// Initialize address book -- Dynamic version
void InitContact(Contact* pc)
{
pc->data = (PeoInfo*)malloc(DEFAULT_SIZE*sizeof(PeoInfo));
// Return value check
if (pc->data == NULL)
{
perror("InitContact");
return;
}
pc->size = 0;
pc->capacity = DEFAULT_SIZE;
}
🧩 Change and add contact function
Just think about it , In addition to initialization, is the function to be changed in the dynamic version compared with the previous version only to add the contact function , Only by increasing can it cross the border , It needs to be expanded, right .
stay contact.c in
// Add contacts -- Dynamic version
void AddContact(Contact* pc)
{
// First, judge whether the address book is full , Consider increasing capacity
if (pc->size == pc->capacity)
{
PeoInfo *ptr = (PeoInfo*)realloc(pc->data, (pc->capacity + INC_SIZE) * sizeof(PeoInfo));
// Return value check
if (ptr != NULL)
{
pc->data = ptr;
pc->capacity += INC_SIZE;// Don't forget to update the capacity variable
printf(" Contact full , Successful automatic capacity increase !");
}
else
{
perror("AddContact");
printf(" Capacity increase failed !\n");
return;
}
}
// Add a person's information
printf(" Please enter a name :>");
scanf("%s", pc->data[pc->size].name);
getchar();
printf(" Please enter age :>");
scanf("%d", &(pc->data[pc->size].age));
printf(" Please enter gender :>");
scanf("%s", pc->data[pc->size].sex);
getchar();
printf(" Please input the phone number :>");
scanf("%s", pc->data[pc->size].tele);
getchar();
printf(" Please enter the address :>");
scanf("%s", pc->data[pc->size].addr);
getchar();
pc->size++;// Indexes +1
printf(" Increase success !\n");
}🧩 Destroy address book on exit
Because dynamic memory is used , So finally, free the memory , And set the pointer to NULL. Define a function to destroy the address book .
stay contact.c in
// Destroy the address book
void DestoryContact(Contact* pc)
{
free(pc->data);
pc->data = NULL;
}
stay test.c in

Basically completed the requirements , This is the implementation of the dynamic version of the address book .
🧩3. dynamic + Document version
🧩 explain
The previous versions we wrote all store data in memory , The data will be destroyed automatically after the program ends , It's temporary , What if we want to make data persistent ? You can save it to a file on your hard disk , This requires file operation .
🧩 Function to save information
I'll put the text file here contact Under the project path .
Here we use wb Binary only writes , Because fwrite Function convenience , You can directly output the structure to a file , Anyway, files only store data , You don't need to open it to understand , To view the information, run the program to read the data into the memory to view , So we need to load data from file into memory later .
// Save address book information to a file
void SaveContact(Contact* pc)
{
FILE* pf = fopen("contact.txt", "wb");
// Return value check
if (NULL == pf)
{
perror("fopen");
return;
}
int i = 0;
for (i = 0; i < pc->size; i++)
{
fwrite(pc->data + i, sizeof(PeoInfo), 1, pf);
}
fclose(pf);
pf = NULL;
}And the data is output to the file before exiting the program .

🧩 Check the full capacity function
When I was writing a dynamic version, I was AddContact The function of checking full capacity and increasing capacity has been written in the function , Now package it as a function to use .
// Check whether it is full , If the capacity is full, it will be automatically increased
static void CheckCapacity(Contact* pc)
{
if (pc->size == pc->capacity)
{
PeoInfo* ptr = (PeoInfo*)realloc(pc->data, (pc->capacity + INC_SIZE) * sizeof(PeoInfo));
// Return value check
if (ptr != NULL)
{
pc->data = ptr;
pc->capacity += INC_SIZE;// Don't forget to update the capacity variable
printf(" Contact full , Successful automatic capacity increase ! The current capacity is :%d\n", pc->capacity);
}
else
{
perror("AddContact");
printf(" Capacity increase failed !\n");
return;
}
}
}🧩 Load data from file to memory
When to load ? Of course, it's time to initialize the address book .
Load all the information stored in the file into memory .
To design a LoadContact Function to implement .
// Initialize address book -- dynamic + Document version
void InitContact(Contact* pc)
{
pc->data = (PeoInfo*)malloc(DEFAULT_SIZE * sizeof(PeoInfo));
// Return value check
if (pc->data == NULL)
{
perror("InitContact");
return;
}
pc->size = 0;
pc->capacity = DEFAULT_SIZE;
LoadContact(pc);// Load the existing information in the file
}actually , At first, our address book capacity was very limited , At the same time, I don't know how much data there is in the file , Then you can't put all the data into memory , Maybe I can't put it down .
We have to take advantage of the dynamic memory feature , therefore CheckCapacity Functions come in handy .
First read the data in batches PeoInfo Type of temporary variable tmp in , Judge whether the current address book capacity is sufficient , If it is insufficient, it will automatically increase capacity , If enough, it will tmp Put the data in the address book , use pc->size As index ( Similar to AddContact Ideas in functions ).
Because it needs to be read many times , So let's use a while loop , What is the condition ?fread Function has a return value , Returns the number of successfully read data of the corresponding type , We read one at a time , So take the return value of this function and 1 Compare , be equal to 1 It indicates that a data is currently read , Then continue with the following code , Finally put the data into the address book .
static void LoadContact(Contact* pc)
{
FILE* pf = fopen("contact.txt", "rb");
// Return value check
if (NULL == pf)
{
perror("LoadContact");
return;
}
PeoInfo tmp = {0};
while (fread(&tmp, sizeof(PeoInfo), 1, pf) == 1)
{
CheckCapacity(pc);
pc->data[pc->size] = tmp;
pc->size++;
}
fclose(pf);
pf = NULL;
}🧩4. The source code file
All three versions are packaged :
link :https://pan.baidu.com/s/1lKF8nq_TpKpA6f1dxsbC_Q?pwd=ylnk
Extraction code :ylnk
🧩 Please look forward to better works ~
Thank you for watching. , Your encouragement is my greatest support , Why don't you make yourself beautiful , Like collection and follow ~

边栏推荐
- Nuxt 路由切换后 asyncData 跨域报错
- Aruba learning notes 06 wireless control AC basic configuration (CLI)
- Spark Learning: Spark implementation of distcp
- Color recognition of regions of interest in pictures and videos based on OpenCV
- Spark Learning: using RDD API to implement inverted index
- 07 Jason module
- Getting started with identityserver4
- Onpropertychange property
- RxJS Beginner Guide
- Financial digital transformation
猜你喜欢
![[MySQL] - deep understanding of index](/img/a6/6ca1356fe11bd33ec7362ce7cdc652.png)
[MySQL] - deep understanding of index

Write a simple memo using localstorage

Android system security - 5.2-apk V1 signature introduction
![[don't bother to strengthen learning] video notes (IV) 2. Dqn realizes maze walking](/img/53/5252c7c6989d142cc2ad6b1c6f513c.png)
[don't bother to strengthen learning] video notes (IV) 2. Dqn realizes maze walking

ASI-20220222-Implicit PendingIntent

Re6:读论文 LeSICiN: A Heterogeneous Graph-based Approach for Automatic Legal Statute Identification fro
![[don't bother to strengthen learning] video notes (II) 2. Write a small example of Q learning](/img/b1/d5c869bc68ba273be2030202f94a55.png)
[don't bother to strengthen learning] video notes (II) 2. Write a small example of Q learning

Leetcode skimming: dynamic planning 03 (climb stairs with minimum cost)

Getting started with sorting - insert sorting and Hill sorting
![[don't bother with reinforcement learning] video notes (I) 1. What is reinforcement learning?](/img/84/48a6a83192a12dafd88bcd74db0955.gif)
[don't bother with reinforcement learning] video notes (I) 1. What is reinforcement learning?
随机推荐
Makefile变量及动态库静态库
The difference between classification and regression
Dark king | analysis of zego low illumination image enhancement technology
S2b2b system standardizes the ordering and purchasing process and upgrades the supply chain system of household building materials industry
Data center: started in Alibaba and started in Daas
Leetcode skimming: dynamic planning 03 (climb stairs with minimum cost)
gnuplot软件学习笔记
Introduction to common ansible modules
[example] v-contextmenu right click menu component
Jenkins post build script does not execute
Linked list - 19. Delete the penultimate node of the linked list
dp最长公共子序列详细版本(LCS)
C#/VB. Net: convert word or EXCEL documents to text
[don't bother to strengthen learning] video notes (III) 2. SARS learning realizes maze walking
Ansible 常用模块介绍
web安全入门-开源防火墙Pfsense安装配置
Wenxin big model raises a new "sail", and the tide of industrial application has arrived
PHP Basics - session control - cookies
Scarcity in Web3: how to become a winner in a decentralized world
Linux deployment mysql8.0