当前位置: 首页 > news >正文

C语言之通讯录的实现

在这里插入图片描述

通讯录实现所需头文件和源文件

Contact.h的功能

声明函数和创建结构体变量

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#define MAX 1000
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_PHONE 12
#define MAX_ADDRESS 30
#define DEFAULT_SZ 3
#define INTC_SZ 2
typedef struct PeoInform
{char name[MAX_NAME];int age;char sex[MAX_SEX];char phone[MAX_PHONE];char address[MAX_ADDRESS];
}PeoInform;//静态
//typedef struct Contact
//{
//    PeoInform data[MAX];
//    int size;
//    
//}Contact;typedef struct Contact
{PeoInform* data;int size;int capacity;
}Contact;void InitContact(Contact* pc);
void AddContact(Contact* pc);
void ShowContact(const Contact* pc);
void DelContact(Contact* pc);
void SearchContact(const Contact* pc);
void MoidfyContact(Contact* pc);
void SortContact(Contact* pc);
void  DerstoryContact(Contact* pc);
void SaveContact(Contact* pc);
void LoadCntact(Contact* pc);

Contact.c

设定通讯录所需的功能和函数的定义

void InitContact(Contact* pc);//初始化函数
void AddContact(Contact* pc);//增加用户
void ShowContact(const Contact* pc);//显示通讯录信息·
void DelContact(Contact* pc);//删除用户信息
void SearchContact(const Contact* pc);//搜索通讯录
void MoidfyContact(Contact* pc);//修改用户信息
void SortContact(Contact* pc);//排序通讯录
void DerstoryContact(Contact* pc);//因动态申请内存所以释放内存
void SaveContact(Contact* pc);//通讯录信息保存到文件
void LoadCntact(Contact* pc);//把文件保存到通讯录中

void InitContact(Contact* pc);

void InitContact(Contact* pc)
{//动态版memset(pc->data, 0, sizeof(pc->data));//第一个参数是起始地址pc->size = 0;pc->capacity = DEFAULT_SZ;PeoInform* ptr= (PeoInform*)calloc(DEFAULT_SZ,sizeof(PeoInform));if (ptr == NULL){perror("InitContact::calloc");return;}pc->data = ptr;//加载文件信息到通讯录//LoadContact(pc);
}

void AddContact(Contact* pc);

void AddContact(Contact* pc)
{assert(pc);check_capacity(pc);printf("请输入名字\n");scanf("%s", pc->data[pc->size].name);printf("请输入年龄\n");scanf("%d", &(pc->data[pc->size].age));printf("请输入性别\n");scanf("%s", pc->data[pc->size].sex);printf("请输入电话\n");scanf("%s", pc->data[pc->size].phone);printf("请输入地址\n");scanf("%s", pc->data[pc->size].address);pc->size++;printf("添加成功\n");
}

``

void ShowContact(const Contact* pc);

	void ShowContact(const Contact * pc){if (pc->size == 0){printf("通讯录为空\n");}else{int i = 0;printf("%-20s\t%-4s\t%-5s\t%-12s\t%-20s\n", "名字", "年龄", "性别", "电话", "地址");for (i = 0; i < pc->size; i++){printf("%-20s\t%-4d\t%-5s\t%-12s\t%-20s\n",pc->data[i].name,pc->data[i].age,pc->data[i].sex,pc->data[i].phone,pc->data[i].address);}}}

void DelContact(Contact* pc);

static int FindByName(const Contact* pc, char name[MAX_NAME])//用于函数内部所以设置为静态
{int i = 0;for (int i = 0; i < pc->size; i++){if (0 == strcmp(pc->data[i].name, name)){return i;}}return -1;
}void DelContact(Contact* pc)
{char name[MAX_NAME];printf("请输入要删除人的名字>");scanf("%s", name);int pos = FindByName(pc,name);if (pos == -1){printf("查询不到联系人\n");}else{int j = 0;for (j = pos; j < pc->size; j++);}
}

void SearchContact(const Contact* pc);

static int FindByName(const Contact* pc, char name[MAX_NAME])//用于函数内部所以设置为静态
{int i = 0;for (int i = 0; i < pc->size; i++){if (0 == strcmp(pc->data[i].name, name)){return i;}}return -1;
}
void SearchContact(const Contact* pc)
{char name[MAX_NAME];printf("请输入查找人的名字\n");scanf("%s", name);int pos = FindByName(pc, name);if (pos == -1){printf("要查找人不存在\n");}else{printf("%-20s\t%-4s\t%-5s\t%-12s\t%-20s\n", "名字", "年龄", "性别", "电话", "地址");printf("%-20s\t%-4d\t%-5s\t%-12s\t%-20s\n",pc->data[pos].name,pc->data[pos].age,pc->data[pos].sex,pc->data[pos].phone,pc->data[pos].address);}
}

void MoidfyContact(Contact* pc);

void MoidfyContact(Contact* pc)
{char name[MAX_NAME];printf("请输入修改联系人的名字>");scanf("%s", name);int pos = FindByName(pc, name);if (pos == -1){printf("要修改人的名字");}else{printf("请输入名字\n");scanf("%s", pc->data[pc->size].name);printf("请输入年龄\n");scanf("%d", &(pc->data[pc->size].age));printf("请输入性别\n");scanf("%s", pc->data[pc->size].sex);printf("请输入电话\n");scanf("%s", pc->data[pc->size].phone);printf("请输入地址\n");scanf("%s", pc->data[pc->size].address);printf("修改完成\n");}
}

void SortContact(Contact* pc);

	void SortContact(Contact* pc){if (pc->size == 0){printf("通讯录没有联系人,请添加\n");}for (int i = 0; i < pc->size-1; i++){for (int j = 0; j < pc->size - 1 - i; j++){if (strcmp((pc->data[j].name), (pc->data[j + 1].name) )> 0){PeoInform tmp;tmp = pc->data[j];pc -> data[j] = pc->data[j+1];pc->data[j+1] = tmp;}}printf("排序成功\n");}}

void DerstoryContact(Contact* pc);

void  DerstoryContact(Contact* pc)
{free(pc->data);pc->data = NULL;pc->capacity = 0;pc->size = 0;pc = NULL;
}

void SaveContact(Contact* pc);

void SaveContact(Contact* pc)//保存文件信息{FILE * pf = fopen("contact.txt", "wb");// 为了输出数据,打开一个二进制文件if (NULL == pf){perror("SaveContact");//打开失败就不用关闭文件了}else{int i = 0;for (i = 0; i < pc->size; i++){/fwrite(pc->data + i, sizeof(PeoInform), 1, pf);//1.结构体地址,一个元素占多少字节,多少个元素,写到pf这个文件}//一次写一个到pf所指文件fclose(pf);pf = NULL;printf("保存成功\n");}}

void LoadCntact(Contact* pc);

	void LoadContact(Contact* pc){//把文件的内容放在通讯录中FILE* pf = fopen("contact.txt","rb"); //为了输入数据,打开一个二进制文件if (pf == NULL){perror("LoadContact");}else//读数据{PeoInform tmp = { 0 };int i = 0;//正常读到1返回1 没读到返0while (fread(&tmp, sizeof(PeoInform), 1, pf))//{check_capacity(pc);pc->data[i] = tmp;pc->size++;i++;}}fclose(pf);pf = NULL;}

contact.c的综合实现

#include "Contact.h"
void check_capacity(Contact* pc)
{if (pc->size = pc->capacity){PeoInform* str = (PeoInform*)realloc(pc->data, (pc->capacity + INTC_SZ) * sizeof(PeoInform));if (str == NULL){perror("check_capacity::realloc");return;}pc->data = str;pc->capacity += INTC_SZ;printf("增容成功");}
}//静态
//void InitContact(Contact* pc)
//{
//	memset(pc->data, 0, sizeof(pc->data));//第一个参数是起始地址
//	pc->size = 0;
//}//动态
void InitContact(Contact* pc)
{memset(pc->data, 0, sizeof(pc->data));//第一个参数是起始地址pc->size = 0;pc->capacity = DEFAULT_SZ;PeoInform* ptr= (PeoInform*)calloc(DEFAULT_SZ,sizeof(PeoInform));if (ptr == NULL){perror("InitContact::calloc");return;}pc->data = ptr;//加载文件信息到通讯录//LoadContact(pc);
}void AddContact(Contact* pc)
{assert(pc);check_capacity(pc);printf("请输入名字\n");scanf("%s", pc->data[pc->size].name);printf("请输入年龄\n");scanf("%d", &(pc->data[pc->size].age));printf("请输入性别\n");scanf("%s", pc->data[pc->size].sex);printf("请输入电话\n");scanf("%s", pc->data[pc->size].phone);printf("请输入地址\n");scanf("%s", pc->data[pc->size].address);pc->size++;printf("添加成功\n");
}static int FindByName(const Contact* pc, char name[MAX_NAME])
{int i = 0;for (int i = 0; i < pc->size; i++){if (0 == strcmp(pc->data[i].name, name)){return i;}}return -1;
}void DelContact(Contact* pc)
{char name[MAX_NAME];printf("请输入要删除人的名字>");scanf("%s", name);int pos = FindByName(pc,name);if (pos == -1){printf("查询不到联系人\n");}else{int j = 0;for (j = pos; j < pc->size; j++);}
}void SearchContact(const Contact* pc)
{char name[MAX_NAME];printf("请输入查找人的名字\n");scanf("%s", name);int pos = FindByName(pc, name);if (pos == -1){printf("要查找人不存在\n");}else{printf("%-20s\t%-4s\t%-5s\t%-12s\t%-20s\n", "名字", "年龄", "性别", "电话", "地址");printf("%-20s\t%-4d\t%-5s\t%-12s\t%-20s\n",pc->data[pos].name,pc->data[pos].age,pc->data[pos].sex,pc->data[pos].phone,pc->data[pos].address);}
}void MoidfyContact(Contact* pc)
{char name[MAX_NAME];printf("请输入修改联系人的名字>");scanf("%s", name);int pos = FindByName(pc, name);if (pos == -1){printf("要修改人的名字");}else{printf("请输入名字\n");scanf("%s", pc->data[pc->size].name);printf("请输入年龄\n");scanf("%d", &(pc->data[pc->size].age));printf("请输入性别\n");scanf("%s", pc->data[pc->size].sex);printf("请输入电话\n");scanf("%s", pc->data[pc->size].phone);printf("请输入地址\n");scanf("%s", pc->data[pc->size].address);printf("修改完成\n");}
}void ShowContact(const Contact * pc){if (pc->size == 0){printf("通讯录为空\n");}else{int i = 0;printf("%-20s\t%-4s\t%-5s\t%-12s\t%-20s\n", "名字", "年龄", "性别", "电话", "地址");for (i = 0; i < pc->size; i++){printf("%-20s\t%-4d\t%-5s\t%-12s\t%-20s\n",pc->data[i].name,pc->data[i].age,pc->data[i].sex,pc->data[i].phone,pc->data[i].address);}}}void SortContact(Contact* pc){if (pc->size == 0){printf("通讯录没有联系人,请添加\n");}for (int i = 0; i < pc->size-1; i++){for (int j = 0; j < pc->size - 1 - i; j++){if (strcmp((pc->data[j].name), (pc->data[j + 1].name) )> 0){PeoInform tmp;tmp = pc->data[j];pc -> data[j] = pc->data[j+1];pc->data[j+1] = tmp;}}printf("排序成功\n");}}void  DerstoryContact(Contact* pc){free(pc->data);pc->data = NULL;pc->capacity = 0;pc->size = 0;pc = NULL;}void SaveContact(Contact* pc){FILE * pf = fopen("contact.txt", "wb");if (NULL == pf){perror("SaveContact");}else{int i = 0;for (i = 0; i < pc->size; i++){fwrite(pc->data + i, sizeof(PeoInform), 1, pf);}fclose(pf);pf = NULL;printf("保存成功\n");}}void LoadContact(Contact* pc){FILE* pf = fopen("contact.txt","rb"); if (pf == NULL){perror("LoadContact");}else{PeoInform tmp = { 0 };int i = 0;while (fread(&tmp, sizeof(PeoInform), 1, pf)){check_capacity(pc);pc->data[i] = tmp;pc->size++;i++;}}fclose(pf);pf = NULL;}

test.h

#include "Contact.h"void menu()
{printf("*********************************\n");printf("**      1. 添加联系人          **\n");printf("**      2. 删除联系人          **\n");printf("**      3. 查找联系人          **\n");printf("**      4. 修改联系人          **\n");printf("**      5. 显示所有联系人      **\n");printf("**      6. 按姓名排序联系人    **\n");printf("**      0. exit                **\n");printf("*********************************\n");
}
void test()
{int input = 0;Contact con;InitContact(&con);do{menu();printf("请选择:>");scanf("%d", &input);switch (input){case 1:AddContact(&con);break;case 2: DelContact(&con);break;case 3:SearchContact(&con);break;case 4:MoidfyContact(&con);break;case 5:ShowContact(&con);break;case 6:SortContact(&con);break;case 0:DerstoryContact(&con);printf("退出通讯录\n");break;default:printf("选择错误\n");break;}} while (input);
}
int main()
{test();return 0;
}

在这里插入图片描述

相关文章:

C语言之通讯录的实现

通讯录实现所需头文件和源文件 Contact.h的功能 声明函数和创建结构体变量 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> #include <stdlib.h> #include <assert.h> #define MAX 1000 #define MAX_NAME 20 #define MAX…...

手把手教大家在 gRPC 中使用 JWT 完成身份校验

文章目录1. JWT 介绍1.1 无状态登录1.1.1 什么是有状态1.1.2 什么是无状态1.2 如何实现无状态1.3 JWT1.3.1 简介1.3.2 JWT数据格式1.3.3 JWT 交互流程1.3.4 JWT 存在的问题2. 实践2.1 项目创建2.2 grpc_api2.3 grpc_server2.4 grpc_client3. 小结上篇文章松哥和小伙伴们聊了在 …...

VSCode远程连接服务器

工作使用服务器的jupyter&#xff0c;直到有一天服务器挂了&#xff0c;然而&#xff0c;代码还没有来得及备份。o(╥﹏╥)o VScode远程连接服务器&#xff0c;使用服务器的资源&#xff0c;代码可以存在本地&#xff0c;可以解决上述困境。 1.官网下载VSCode.网址https://cod…...

【C++】-- 异常

目录 C语言传统的处理错误的方式 C异常概念 异常的使用 异常的抛出和捕获 自定义异常体系 异常的重新抛出 异常安全 异常规范&#xff08;C期望&#xff09; C标准库的异常体系 异常的优缺点 C异常的优点 C异常的缺点 总结 C语言传统的处理错误的方式 传统的错误…...

Java中的Stack与Queue

文章目录一、栈的概念及使用1.1 概念1.2 栈的使用1.3 栈的模拟实现二、队列的概念及使用2.1 概念2.2 队列的使用2.3 双端队列(Deque)三、相关OJ题3.1 用队列实现栈。3.2 用栈实现队列。总结一、栈的概念及使用 1.1 概念 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在…...

xilinx FPGA在线调试方法总结(vivado+ila+vio)

本文主要介绍xilinx FPGA开发过程中常用的调试方法&#xff0c;包括ILA、VIO和TCL命令等等&#xff0c;详细介绍了如何使用。一、FPGA调试基本原则根据实际的输出结果表现&#xff0c;来推测可能的原因&#xff0c;再在模块中加ILA信号&#xff0c;设置抓信号条件&#xff0c;逐…...

自动化测试——css元素定位

文章目录一、css定位场景二、css相对定位的优点三、css的调试方法1、表达式中含有字符串&#xff1a;表达式中的引号一定和外面字符串的引号相反四、css基础语法1、标签定位2、class定位特别注意&#xff1a;当class类型的属性值包含多个分割值&#xff0c;$(.s_tab s_tab_1z9n…...

ChatGPT可能马上取代你,这是它能做的十个工作

ChatGPT 的横空出世,在业界掀起了惊涛骇浪。专家表示,ChatGPT 和相关人工智能技术可能会威胁到一些工作岗位,尤其是白领工作。 自去年11月发布以来,新型聊天机器人模型 ChatGPT 已经被用于各种各样的工作:撰写求职信、编写儿童读物,甚至帮助学生在论文中作弊。谷歌公司发…...

ubuntu转储coredump

方法一&#xff1a; 输入以下命令即可,其中${USER}为自己电脑的用户名&#xff1a; ulimit -c unlimited echo "/home/${USER}/core.%p" > /proc/sys/kernel/core_pattern 方法二&#xff1a; Disable apport : sudo systemctl stop apport.servicesudo system…...

基于单片机的毕业设计推荐

** 2023基于单片机的毕业设计推荐&#xff1a; ** 1、基于51单片机的多功能门禁系统&#xff08;低端、功能限制较大&#xff09;。 2、基于单片机的多功能实时时钟。 3、基于单片机的音乐播放器。 4、基于STM32单片机的多功能门禁系统&#xff08;高端、没有限制&#xff09…...

APP测试中ios和androis的区别,有哪些注意点

目录 一、运行机制不同 二、对app内存消耗处理方式不同 三、后台制度不同 四、最高权限指令不同 五、推送机制不同 六、抓取方式不同 七、灰度发版机制不同 八、审核机制不同 总结感谢每一个认真阅读我文章的人&#xff01;&#xff01;&#xff01; 重点&#xff1a;…...

使用 Xcode 创建第一个 Objective-C 命令行程序 HelloWorld

总目录 iOS开发笔记目录 从一无所知到入门 文章目录创建项目运行项目&#xff0c;查看日志输出同一项目下新增子目录&#xff0c;切换要运行的 Target创建项目 打开 Xcode &#xff0c;Create a new Xcode project 接下来的默认界面&#xff1a; 切换到 macOS 下&#xff…...

【蓝桥杯集训8】哈希表专题(3 / 3)

目录 手写哈希表 1、开放寻址法 2、拉链法 字符串前缀哈希表法 2058. 笨拙的手指 - 哈希表 秦九韶算法&#xff08;进制转换&#xff09; 枚举 秦九韶算法——将x进制数转化为十进制数 手写哈希表 活动 - AcWing 1、开放寻址法 设 h(x)k&#xff0c;也就是 x 的哈希值…...

Java Scanner 类,超详细整理,适合新手入门

目录 一、什么是 Java Scanner 类&#xff1f; 二、引用数据类型 1、引用数据类型的定义 三、Scanner 类有哪些常用方法&#xff1f; hasNext()用法 四、next() 与 nextLine() 区别 next(): nextLine()&#xff1a; 五、使用 next 方法 五、使用 nextLine方法 一、什…...

干货 | 中小企业选型 Elasticsearch 避坑指南

1、线上常见问题在我线下对接企业或线上交流的时候&#xff0c;经常会遇到各种业务场景不同的问题。比如&#xff0c;常见问题归类如下&#xff1a;常见问题1&#xff1a;ES 适合场景及架构选型问题。公司的核心业务是做企业员工健康管理&#xff0c;数据来自电子化后的员工体检…...

全局组件和局部组件

全局组件第一种定义方法&#xff1a;A、创建自己的组件&#xff1a;Loading.vueB、在main.js文件中引入组件并注册import Vue from vue import App from ./App.vue import * as filters from ./filterimport quanjuzujian from ./components/quanjuzujian.vueVue.component(qua…...

提取括号中的内容

正则能解决不嵌套的括号内容提取问题遇到一个问题&#xff0c;就是需要提取字符串中每一个中括号里的内容&#xff0c;在网上搜了一下&#xff0c;发现用正则表达式(\[[^\]]*\])可以提取中括号中的内容&#xff0c;以下面文本为匹配对象&#xff1a;PerformanceManager[第1个中…...

数据结构-算法的空间复杂度(1.2)

目录 1.空间复杂度 1.1 例子 1.2 空间的特殊性质 写在最后&#xff1a; 1.空间复杂度 空间复杂度也是一个数学表达式&#xff0c; 是对一个算法在运行过程中临时占用存储空间大小的量度。 他也是用大O渐进表示法。 1.1 例子 例1&#xff1a; 冒泡排序&#xff1a; v…...

【总结】python3启动web服务引发的一系列问题

背景 在某行的实施项目&#xff0c;需要使用python3环境运行某些py脚本。 由于行内交付的机器已自带python3 &#xff0c;没有采取自行安装python3&#xff0c;但是运行python脚本时报没有tornado module。 错误信息 ModuleNotFoundError&#xff1a;No module named ‘torn…...

Linux:基于libevent读写管道代码,改进一下上一篇变成可以接收键盘输入

对上一篇进行改进&#xff0c;变成可以接收键盘输入&#xff0c;然后写入管道&#xff1a; 读端代码&#xff1a; #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <s…...

RocketMQ延迟消息机制

两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数&#xff0c;对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后&#xf…...

【WiFi帧结构】

文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成&#xff1a;MAC头部frame bodyFCS&#xff0c;其中MAC是固定格式的&#xff0c;frame body是可变长度。 MAC头部有frame control&#xff0c;duration&#xff0c;address1&#xff0c;address2&#xff0c;addre…...

oracle与MySQL数据库之间数据同步的技术要点

Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异&#xff0c;它们的数据同步要求既要保持数据的准确性和一致性&#xff0c;又要处理好性能问题。以下是一些主要的技术要点&#xff1a; 数据结构差异 数据类型差异&#xff…...

linux 错误码总结

1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面

代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口&#xff08;适配服务端返回 Token&#xff09; export const login async (code, avatar) > {const res await http…...

【HTML-16】深入理解HTML中的块元素与行内元素

HTML元素根据其显示特性可以分为两大类&#xff1a;块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...

大数据学习(132)-HIve数据分析

​​​​&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4…...

IP如何挑?2025年海外专线IP如何购买?

你花了时间和预算买了IP&#xff0c;结果IP质量不佳&#xff0c;项目效率低下不说&#xff0c;还可能带来莫名的网络问题&#xff0c;是不是太闹心了&#xff1f;尤其是在面对海外专线IP时&#xff0c;到底怎么才能买到适合自己的呢&#xff1f;所以&#xff0c;挑IP绝对是个技…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...