广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C语言模拟实现通讯录程序过程
  • 151
分享到

C语言模拟实现通讯录程序过程

C语言模拟实现通讯录C语言模拟通讯录C语言通讯录 2023-02-14 18:02:43 151人浏览 独家记忆
摘要

目录一、前言二、正文1.大体框架2.界面显示3. 创建通讯录4.初始化通讯录5.增加联系人6.显示联系人7. 删除联系人8.查找联系人9.修改联系人10. 排序联系人一、前言 在上一

一、前言

在上一章的结构体的学习中,相信小伙伴们或多或少都有所收获,但是有的小伙伴可能会问,结构体到底能用来做什么呢?今天,我们就借助结构体和之前所学的知识来实现通讯录。

二、正文

1.大体框架

相信在座的小伙伴们一定有人做过类似的小游戏或项目编程的大忌就是将所有的代码都放在同一个文件里,写的时候有多好爽快,后期对代码进行修改和维护的时候就有痛苦。这期通讯录的实现我们大致分为三个模块,一个用于测试通讯录,即对各种函数的调用【text.c】;另一个用于通讯录的实现,其中放置着通讯录功能的具体实现【contact.c】;最后一个就是函数的声明了[contact.h].

2.界面显示

就像之前的扫雷与三子棋游戏一样,这个通讯录的第一步一定是要让使用者看到通讯录的页面,继而在使用者选择之后进行下一步的操作。因而我们仍旧采取do while 循环,先将页面显示,再根据使用者的输入进行相应的操作。具体实现代码如下:

void bubble_sort(int arr[], int sz)
{
	//趟数
	int i = 0;
	for (i = 0; i < sz - 1; i++)
	{
		//一趟冒泡排序的过程
		int j = 0;
		for (j = 0; j < sz - 1 - i; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
            }
		}
	}
}

在以上代码的逻辑下,使用者刚开始就能够看到我们设置好的界面,并进行功能的输入,如果输入为0就退出通讯录,通讯录为功能相应的数字就进行相应的功能【还未填写完整】,若为其他数字,则重新输入。

3. 创建通讯录

为了实现我们菜单中的各个功能,首先我们要有这些功能的受体——通讯录,只有创建好通讯录 ,才能进行功能的操作。在生活中,我们手机上的通讯录都存有联系人的相关信息,例如姓名,年龄,性别,手机号码等等 ,其次在后面的功能中我们还需要知道这个通讯录中联系人的数量是多少。显然,我们需要一个自定义结构变量来定义通讯录,在这个结构体中有两个变量,一个是存放联系人信息的变量,另一个是存放联系人数量的变量。而存放联系人的信息显然需要一个数组,数组的大小即对应着能存放多少联系人,而数组中的元素就是联系人的信息,这也无法用一个单一类型变量来定义,所以我们还需要额外定义一个结构体变量来代表联系人的各种信息。具体代码如下:

//结构体——联系人的信息
struct peo
{
	char name[20];    //姓名
	char sex[10];     //性别
	int age;          //年龄  
	char addr[40];    //地址
	char tel[20];     //电话
};
//结构体——通讯录
typedef struct contact
{
	struct peo Peo[contact_num];	//通讯录中联系人的信息
	int sz;							//当前存放联系人的个数
}contact;

4.初始化通讯录

在通讯录的创建之后,就是对其的初始化了,为了方便,我们就都置成0就好了。

//Init_Contact——初始化通讯录
 void Init_Contact(contact* pc)
{
	pc->sz = 0;
	memset(pc, 0, sizeof(pc->Peo));
}

5.增加联系人

在通讯录的创建和初始化完成之后,就是通讯录功能的实现了。首先是“增加联系人”这一功能。我们先是定义一个函数,这个函数的参数就是我们的通讯录,采用传递通讯录地址的方式,返回值为空,因为我们只是对通讯录的内容进行改变,并不需要返回任何东西。然后是函数的具体实现,我们要做的是在联系人信息这一数组中添加一个联系人,并在添加之后将通讯录当前存储的联系人数量+1。此外如果通讯录已满,我们需要提醒使用者无法再添加联系人。具体代码如下:

 //Add——增加联系人
 void Add(contact* Contact)
 {
	 assert(Contact);
	 if (Contact->sz < contact_num)
	 {
		 printf("请输入联系人的姓名:>\n");
		 scanf("%s", (Contact->Peo[Contact->sz]).name);
		 printf("请输入联系人的性别:>\n");
		 scanf("%s", Contact->Peo[Contact->sz].sex);
		 printf("请输入联系人的年龄:>\n");
		 scanf("%d", &(Contact->Peo[Contact->sz].age));
		 printf("请输入联系人的地址:>\n");
		 scanf("%s", Contact->Peo[Contact->sz].addr);
		 printf("请输入联系人的电话:>\n");
		 scanf("%s", Contact->Peo[Contact->sz].tel);
		 Contact->sz++;
	 }
	 else
		 printf("通讯录已满无法添加\n");
 }

6.显示联系人

为了观察我们在执行增加联系人这个函数是否成功,我们接下来进行“显示联系人”这一功能的实现。同样的先是定义显示联系人这一函数,函数参数是通讯录,采取传址调用的方式,无需返回任何参数。函数的实现就是依据通讯录中所存储的联系人数量,来调用存储联系人信息的数组,并将其显示在屏幕上,为了数据显示的整齐和美观,笔者对打印的数据类型进行了小小的改善,对数据所占空间进行了设置,并将数据左对齐并在数据后输出一个水平制表符。

 //Show——展示联系人
  void Show( const contact* Contact)
 {
	 assert(Contact);
	 int pos = 0;    //联系人对应下标
	 printf("%-20s\t%-10s\t%-4s\t%-40s\t%-20s\n","姓名", "性别", "年龄", "地址", "电话");
	 for (pos = 0; pos < Contact->sz; pos++)
	 {
		 printf("%-20s\t%-10s\t%-4d%\t%-40s\t%-20s\n", Contact->Peo[pos].name,
			 Contact->Peo[pos].sex,
			 Contact->Peo[pos].age,
			 Contact->Peo[pos].addr,
			 Contact->Peo[pos].tel);
	 }
  }

7. 删除联系人

首先是“删除联系人”这一函数的定义,参数为通讯录这一结构体,采取传址调用的方式,返回参数无。继而是函数具体的实现,笔者是根据使用者所输入的所要删除联系人的姓名来找到联系人在数组中对应的下标,从而进行各项信息的删除。这里有个小技巧,无论是删除联系人,修改联系人,搜索联系人都需要在根据输入的姓名对联系人进行查找,因而我们可以将这个功能封装成一个函数,在使用这一功能的时候只需要调用就行了。具体代码实现如下:

//Find_by_name——通过姓名,找到联系人所对应的下标
  int Find_by_name( const contact* Contact, char *name)
  {
	 int i = 0;
	 for (i = 0; i < Contact->sz; i++)
	 {
		  if (strcmp(&(Contact->Peo[i].name),name)==0)
			  return i;
	 }
	 return -1;
  }
//Del——删除联系人
  void Del(contact* Contact)
  {
	  char name[20] = { 0 };
	  int i = 0;
	  printf("请输入要删除的联系人:>");
	  scanf("%s", name);
	  int pos = Find_by_name(Contact, &name);
	  if (-1 == pos)
	  {
		  printf("该联系人不存在\n");
		  return;
	  }
	  else
	  {
		  for (i = pos; i < Contact->sz-1; i++)
		  {
			  Contact->Peo[i] = Contact->Peo[i + 1];
		  }
		  Contact->sz--;
	  }
  }

8.查找联系人

首先是对“查找联系人”函数的定义,函数参数为通讯录,采取传址调用的方式,返回参数为0。然后是具体功能的实现,先是根据输入的姓名查找到对应的下标,再将其显示在屏幕上。具体代码如下:

//Search——搜索联系人
  void Search(const contact* Contact)
  {
	  char name[20] = {0};
	  printf("请输入要寻找的联系人:>");
	  scanf("%s", name);
	  int pos= Find_by_name(Contact, &name);
	  if (-1==pos)
	  {
		printf("该联系人不存在\n");
		return;
	  }
	  else
	  {
		printf("%-10s\t%-6s\t%-4s\t%-40s\t%-20s\n", "姓名", "性别", "年龄", "地址", "电话");
		printf("%-10s\t%-6s\t%-4d%\t%-40s\t%-20s\n", Contact->Peo[pos].name,
			Contact->Peo[pos].sex,
			Contact->Peo[pos].age,
			Contact->Peo[pos].addr,
			Contact->Peo[pos].tel);
	  } 
  }

9.修改联系人

首先是对“修改联系人”函数的定义,函数参数为通讯录,采取传址调用的方式,返回参数为0。然后是具体功能的实现,先是根据输入的姓名查找到对应的下标,再依据添加联系人的代码实现联系人信息的修改。具体代码如下:

//Modify——修改联系人
  void Modify(contact* Contact)
  {
	  assert(Contact);
	char name[20] = { 0 };
	printf("请输入要修改的联系人\n");
	scanf("%s", name);
	int pos = Find_by_name(Contact, &name);
	if (-1 == pos)
	{
		printf("该联系人不存在\n");
		return;
	}
	else
	{
		printf("请输入联系人的姓名:>\n");
		scanf("%s", (Contact->Peo[pos]).name);
		printf("请输入联系人的性别:>\n");
		scanf("%s", Contact->Peo[pos].sex);
		printf("请输入联系人的年龄:>\n");
		scanf("%d", &(Contact->Peo[pos].age));
		printf("请输入联系人的地址:>\n");
		scanf("%s", Contact->Peo[pos].addr);
		printf("请输入联系人的电话:>\n");
		scanf("%s", Contact->Peo[pos].tel);
	}
  }

10. 排序联系人

对联系人排序依据有很多,这里仅对联系人的年龄进行排序。采取冒泡排序的方式,冒泡排序的实现在前面的推文已经介绍过了,有兴趣的小伙伴可以康一康。https://www.jb51.net/article/275286.htm

//sort——按照年龄对联系人进行排序
  void sort(contact* Contact,contact* tmp)
  {
	  //执行冒泡排序的趟数
	  int i = 0;
	  for (i = 0; i < Contact->sz - 1; i++)
	  {
		  //一趟冒泡排序中交换的次数
		  int j = 0;
		  for (j = 0; j < Contact->sz - 1-i; j++)
		  {
			  if (Contact->Peo[j].age > Contact->Peo[j + 1].age)
			  {
				  tmp->Peo[0] = Contact->Peo[j];
				  Contact->Peo[j] = Contact->Peo[j + 1];
				  Contact->Peo[j + 1] = tmp->Peo[0];
			  }
		  }
	  }
  }

到这里,整个通讯录就写完了,整体的代码如下:

//main.c
#include "contact.h"
//菜单
void menu()
{
	printf("******************************\n");
	printf("*****  1.Add    2.Del    *****\n");
	printf("*****  3.Search 4.Modify *****\n");
	printf("*****  5.Show   6.Sort   *****\n");
	printf("***    0.Exit            *****\n");
	printf("******************************\n");
}
int main()
{
	contact	Contact;	//创建通讯录
	contact tmp;
	Init_Contact(&Contact);		//初始化通讯录
	Init_Contact(&tmp);		
	int input = 0;
	do
	{
		menu();		//打印菜单
		printf("请选择你所需的功能:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			Add(&Contact);
			break;
		case 2:
			Del(&Contact);
			break;
		case 3:
			Search(&Contact);
			break;
		case 4:
			Modify(&Contact);
			break;
		case 5:
			Show(&Contact);
			break;
		case 6:
			sort(&Contact,&tmp);
			break;
		case 0:
			printf("退出通讯录\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
		}
	}
	while (input);
	return 0;
}
//contact.h
#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#define contact_num 100
#include <stdio.h>
#include <string.h>
#include <assert.h>
//结构体——联系人的信息
struct peo
{
	char name[20];	//姓名
	char sex[10];	//性别
	int age;		//年龄
	char addr[40];	//地址
	char tel[20];	//电话
};
//结构体——通讯录
typedef struct contact
{
	struct peo Peo[contact_num];	//通讯录中联系人的信息
	int sz;							//当前存放联系人的个数
}contact;
void Init_Contact(contact* pc);	//初始化通讯录
void Add(contact* Contact);		//添加联系人
void Show(const contact* Contact);	//展示联系人
void Search(const contact* Contact);	//搜索联系人
void Del(contact* Contact);		//删除联系人
void Modify(contact* Contact);	//修改联系人
void sort(contact* Contact,contact* tmp);	//排序联系人——年龄
//contact.c
#include "contact.h"
//Init_Contact——初始化通讯录
 void Init_Contact(contact* pc)
{
	pc->sz = 0;
	memset(pc, 0, sizeof(pc->Peo));
}
 //Add——增加联系人
 void Add(contact* Contact)
 {
	 assert(Contact);
	 if (Contact->sz < contact_num)
	 {
		 printf("请输入联系人的姓名:>\n");
		 scanf("%s", (Contact->Peo[Contact->sz]).name);
		 printf("请输入联系人的性别:>\n");
		 scanf("%s", Contact->Peo[Contact->sz].sex);
		 printf("请输入联系人的年龄:>\n");
		 scanf("%d", &(Contact->Peo[Contact->sz].age));
		 printf("请输入联系人的地址:>\n");
		 scanf("%s", Contact->Peo[Contact->sz].addr);
		 printf("请输入联系人的电话:>\n");
		 scanf("%s", Contact->Peo[Contact->sz].tel);
		 Contact->sz++;
	 }
	 else
		 printf("通讯录已满无法添加\n");
 }
 //Show——展示联系人
  void Show( const contact* Contact)
 {
	  assert(Contact);
	 int pos = 0;
	 printf("%-10s\t%-6s\t%-4s\t%-40s\t%-20s\n","姓名", "性别", "年龄", "地址", "电话");
	 for (pos = 0; pos < Contact->sz; pos++)
	 {
		 printf("%-10s\t%-6s\t%-4d%\t%-40s\t%-20s\n", Contact->Peo[pos].name,
			 Contact->Peo[pos].sex,
			 Contact->Peo[pos].age,
			 Contact->Peo[pos].addr,
			 Contact->Peo[pos].tel);
	 }
  }
  //Find_by_name——通过姓名,找到联系人所对应的下标
  int Find_by_name( const contact* Contact, char *name)
  {
	 int i = 0;
	 for (i = 0; i < Contact->sz; i++)
	 {
		  if (strcmp(&(Contact->Peo[i].name),name)==0)
			  return i;
	 }
	 return -1;
  }
  //Search——搜索联系人
  void Search(const contact* Contact)
  {
	  char name[20] = {0};
	  printf("请输入要寻找的联系人:>");
	  scanf("%s", name);
	  int pos= Find_by_name(Contact, &name);
	  if (-1==pos)
	  {
		printf("该联系人不存在\n");
		return;
	  }
	  else
	  {
		printf("%-10s\t%-6s\t%-4s\t%-40s\t%-20s\n", "姓名", "性别", "年龄", "地址", "电话");
		printf("%-10s\t%-6s\t%-4d%\t%-40s\t%-20s\n", Contact->Peo[pos].name,
			Contact->Peo[pos].sex,
			Contact->Peo[pos].age,
			Contact->Peo[pos].addr,
			Contact->Peo[pos].tel);
	  } 
  }
  //Del——删除联系人
  void Del(contact* Contact)
  {
	  char name[20] = { 0 };
	  int i = 0;
	  printf("请输入要删除的联系人:>");
	  scanf("%s", name);
	  int pos = Find_by_name(Contact, &name);
	  if (-1 == pos)
	  {
		  printf("该联系人不存在\n");
		  return;
	  }
	  else
	  {
		  for (i = pos; i < Contact->sz-1; i++)
		  {
			  Contact->Peo[i] = Contact->Peo[i + 1];
		  }
		  Contact->sz--;
	  }
  }
  //Modify——修改联系人
  void Modify(contact* Contact)
  {
	  assert(Contact);
	char name[20] = { 0 };
	printf("请输入要修改的联系人\n");
	scanf("%s", name);
	int pos = Find_by_name(Contact, &name);
	if (-1 == pos)
	{
		printf("该联系人不存在\n");
		return;
	}
	else
	{
		printf("请输入联系人的姓名:>\n");
		scanf("%s", (Contact->Peo[pos]).name);
		printf("请输入联系人的性别:>\n");
		scanf("%s", Contact->Peo[pos].sex);
		printf("请输入联系人的年龄:>\n");
		scanf("%d", &(Contact->Peo[pos].age));
		printf("请输入联系人的地址:>\n");
		scanf("%s", Contact->Peo[pos].addr);
		printf("请输入联系人的电话:>\n");
		scanf("%s", Contact->Peo[pos].tel);
	}
  }
  //sort——按照年龄对联系人进行排序
  void sort(contact* Contact,contact* tmp)
  {
	  //执行冒泡排序的趟数
	  int i = 0;
	  for (i = 0; i < Contact->sz - 1; i++)
	  {
		  //一趟冒泡排序中交换的次数
		  int j = 0;
		  for (j = 0; j < Contact->sz - 1-i; j++)
		  {
			  if (Contact->Peo[j].age > Contact->Peo[j + 1].age)
			  {
				  tmp->Peo[0] = Contact->Peo[j];
				  Contact->Peo[j] = Contact->Peo[j + 1];
				  Contact->Peo[j + 1] = tmp->Peo[0];
			  }
		  }
	  }
  }

到此这篇关于C语言模拟实现通讯录程序过程的文章就介绍到这了,更多相关C语言通讯录内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: C语言模拟实现通讯录程序过程

本文链接: https://www.lsjlt.com/news/196094.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C语言模拟实现通讯录程序过程
    目录一、前言二、正文1.大体框架2.界面显示3. 创建通讯录4.初始化通讯录5.增加联系人6.显示联系人7. 删除联系人8.查找联系人9.修改联系人10. 排序联系人一、前言 在上一...
    99+
    2023-02-14
    C语言模拟实现通讯录 C语言模拟通讯录 C语言通讯录
  • C语言实现通讯录程序
    本文实例为大家分享了C语言实现通讯录程序的具体代码,供大家参考,具体内容如下 设计要求: 可以存放1000个人的信息,每个人的信息包括姓名、年龄、性别、电话、住址 通讯录功能包括: ...
    99+
    2022-11-12
  • C语言模拟实现动态通讯录
    目录1.模拟实现通讯录总体架构一览图2.文件执行任务3.分模块实现 测试模块 test.c头文件 功能函数声明 contact.h功能函数逐一实现1.模拟实现通讯录总体架构...
    99+
    2022-11-12
  • C语言实现通讯录系统程序
    本文实例为大家分享了C语言实现通讯录系统程序的具体代码,供大家参考,具体内容如下 前言 利用链表增、删、改、查功能以及文件来完成通讯录系统。通讯录中包含联系人的基本信息:姓名、联系电...
    99+
    2022-11-13
  • C语言之通讯录的模拟实现代码
    目录纲要:一.通讯录的静态版本    1.添加联系人  2.展示联系人  3.删除联系人  4.查找联系人信息  5.修改联系人信息  6.排序联系人 --- 我们使用 qsort ...
    99+
    2022-11-12
  • C语言怎么模拟实现动态通讯录
    本篇内容主要讲解“C语言怎么模拟实现动态通讯录”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C语言怎么模拟实现动态通讯录”吧!目录模拟实现通讯录总体架构一览图文件执行任务分模块实现 测...
    99+
    2023-06-20
  • C语言如何实现通讯录系统程序
    本文小编为大家详细介绍“C语言如何实现通讯录系统程序”,内容详细,步骤清晰,细节处理妥当,希望这篇“C语言如何实现通讯录系统程序”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。前言利用链表增、删、改、查功能以及文件...
    99+
    2023-07-02
  • C语言实现可增容动态通讯录详细过程
    目录创建可自动扩容的通讯录添加用户信息删除用户信息查找联系人修改用户信息以名字将用户排序销毁通讯录创建可自动扩容的通讯录 这里我们想实现通讯录自动扩容,不够了能扩大内存,变得稍微有点...
    99+
    2022-11-13
  • 用C语言实现通讯录
    相信大家都见识过通讯录,通讯录里面一般有的内容为姓名,联系方式,年龄等信息。通讯录的主要功能有:增加、删除、查找、排序、修改、展示等操作。 那么具体应该用C语言怎么实现这个呢?接下来...
    99+
    2022-11-13
  • C语言实现简易通讯录完整流程
    目标:通讯录可以存放1000个人信息,人的信息:性别名字年龄电话住址 菜单打印 1.增加联系人 2.删除联系人 3.查找联系人(修改) 4.名字排序联系人 5.展示 6.清空 分析:...
    99+
    2022-11-13
  • C语言实现通讯录系统课程设计
    本文实例为大家分享了C语言实现通讯录系统的具体代码,供大家参考,具体内容如下 设计要求 1.单位、个人信息查询2.打开、写入保存这些信息的文件 完整代码 #include <s...
    99+
    2022-11-13
  • C语言动态与静态分别实现通讯录详细过程
    目录前言:一.静态通讯录的实现1.环境的分工逻辑2.待实现的功能3.contact.h4.contact.c5.test.c6.实现效果二.通讯录动态的实现1.contact.h2....
    99+
    2022-11-13
  • C语言与C++动态通讯录超详细实现流程
    目录1、思路以及要实现的功能2、详细步骤2.1 打印菜单界面(建一个源文件test.c)2.2 主函数2.3 初始化函数与加载函数2.4 增加联系人函数AddContact2.5 删...
    99+
    2022-11-13
  • 详解C语言之实现通讯录
    目录基本思路和代码实现其他探讨总结基本思路和代码实现 为了代码清晰易读,我们创建一个Main.c源文件用来实现代码的基本逻辑。创建一个Contact.h源文件用于封装实现功能的函数,...
    99+
    2022-11-12
  • C语言实现通讯录小项目
    本文实例为大家分享了C语言实现通讯录小项目的具体代码,供大家参考,具体内容如下 编写程序实现通讯录的基本功能,可以做到增,删,查,改,打印通讯录,等等功能 test.c #inc...
    99+
    2022-11-12
  • C语言实现通讯录小功能
    本文实例为大家分享了C语言实现通讯录功能的具体代码,供大家参考,具体内容如下 头文件contact.h #pragma once #define _CRT_SECURE_NO_...
    99+
    2022-11-12
  • C语言链表实现通讯录系统课程设计
    本文实例为大家分享了C语言链表实现通讯录系统的具体代码,供大家参考,具体内容如下 流程图 概要设计 1、数据结构 选择单链表来完成所有操作,便于插入和删除,不利于排序。 2、程序模...
    99+
    2022-11-13
  • C语言实现通讯录功能的流程与代码
    用C语言制作一个拥有添加,删除,查找,修改,排序,清空,打印功能的通讯录 用分模块的方法来实现这个通讯录,函数的声明,类型的声明放在一个.h文件中,函数的实现放在一个.c文件中,在主...
    99+
    2022-11-13
  • C语言实现简易通讯录实例
    目录一、问题描述二、功能介绍二、实现流程1.创建通讯录2.创建源文件test.c3.创建源文件contact.c4.删除通讯录联系人信息 (DelContact函数实现)5...
    99+
    2022-11-13
  • C语言通过三种方法实现属于你的通讯录
    目录一、基础版本1.1 通讯录的个人信息(结构体来实现)1.2通讯录名单1.3人员初始化1.4菜单1.5主函数二、功能的实现2.1、增加人数2.2、删除人数2.3、查找2.4、展示2...
    99+
    2022-11-21
    C语言实现通讯录 C语言 通讯录
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作