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

【进阶C语言】静态版通讯录的实现(详细讲解+全部源码)

在这里插入图片描述
前言

📕作者简介:热爱跑步的恒川,正在学习C/C++、Java、Python等。
📗本文收录于C语言进阶系列,本专栏主要内容为数据的存储、指针的进阶、字符串和内存函数的介绍、自定义类型结构、动态内存管理、文件操作等,持续更新!
📘相关专栏Python,Java等正在发展,拭目以待!


📕本期内容恒川将会给大家带来实现通讯录的讲解,与上期所学的结构体内容相结合,我将会用C语言来实现通讯录的系统,并且能存放百人甚至千人的信息,每个人的信息包括:姓名、性别、年龄、电话、地址,并包含增加联系人、删除指定联系人、查找指定联系人、修改指定联系人、显示联系人信息、排序联系人等功能
📗通讯录和恒川之前写的三子棋和扫雷一样,都是多文件的形式,大家可以参考恒川之前C语言初阶系列的专栏


静态版本通讯录

  • 1. 配置运行环境
  • 2. 通讯录的实现
    • 2.1 通讯录的功能目录
    • 2.2 增加信息功能代码的实现
    • 2.3 显示信息功能代码的实现
    • 2.3 删除信息功能代码的实现
    • 2.4 查询信息功能代码的实现
    • 2.5 修改信息功能代码的实现
    • 2.6 按名字排序信息功能代码的实现
  • 3. 完整静态版本通讯录的全部源码
    • 3.1 contact.c
    • 3.2 contact.h
    • 3.3 test.c
  • 4. 静态版本通讯录的缺点

1. 配置运行环境

本通讯录运用到了三个文件
test.c //测试通讯录的相关功能
contact.h //声明
contact.c //通讯录的实现模块

2. 通讯录的实现

想要做通讯录,首要任务就是要把模块想好。
先打印一个通讯录的界面菜单

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");
}

2.1 通讯录的功能目录

通讯录的功能有7种

  • 增加联系人
  • 删除指定联系人
  • 查找联系人
  • 修改联系人的信息
  • 对联系人的排序
  • 显示联系人的信息
  • 退出通讯录

创建人的信息的结构体类型
第一步是封装一个人的信息的结构体类型
由于封装的结构体类型的名字太长,总是写的话感觉太麻烦了
对 struct PeoInfo进行了typdef类型重命名
struct PeoInfp 改成 PeoInfp

//表示一个人的信息
typedef struct PeoInfo
{char name[20];int age;char sex[5];char tele[12];char addr[30];
}PeoInfo;

以上的数值如果以后会经常用到的话,可以用#define 来定义,方便以后修改

#define MAX 100
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_TELE 12
#define MAX_ADDR 30

2.2 增加信息功能代码的实现

//增加通讯录信息
void AddContact(Contact* pc)
{if (DATA_MAX == pc->sz){printf("通讯录信息存储空间已满!\n");return;}printf("请输入名字:> ");scanf("%s", pc->data[pc->sz].name);printf("请输入年龄:> ");scanf("%d", &(pc->data[pc->sz].age));printf("请输入性别:> ");scanf("%s", pc->data[pc->sz].sex);printf("请输入电话:> ");scanf("%s", pc->data[pc->sz].tele);printf("请输入住址:> ");scanf("%s", pc->data[pc->sz].addr);printf("信息添加成功!\n");pc->sz++;
}

2.3 显示信息功能代码的实现

void ShowContact(const Contact* pc)
{int i = 0;//姓名      年龄      性别     电话      地址//zhangsan 20        男      123456    北京////打印标题printf("%-10s %-4s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");//打印数据for (i = 0; i < pc->sz; i++){printf("%-10s %-4d %-5s %-12s %-30s\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tele, pc->data[i].addr);}
}

2.3 删除信息功能代码的实现

void DelContact(pContact pc)
{char name[MAX_NAME] = { 0 };if (pc->sz == 0){printf("通讯录为空,无法删除\n");return;}//删除//1. 找到要删除的人 - 位置(下标)printf("输入要删除人的名字:>");scanf("%s", name);int pos = FindByName(pc, name);if (pos == -1){printf("要删除的人不存在\n");return;}int i = 0;//2. 删除 - 删除pos位置上的数据for (i = pos; i<pc->sz-1; i++){pc->data[i] = pc->data[i + 1];}pc->sz--;printf("删除成功\n");
}

2.4 查询信息功能代码的实现

void SearchContact(const Contact* pc)
{char name[MAX_NAME] = {0};printf("请输入要查找人的名字:>");scanf("%s", name);//查找int pos = FindByName(pc, name);if (pos == -1){printf("要查找的人不存在\n");return;}//打印printf("%-10s %-4s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");//打印数据printf("%-10s %-4d %-5s %-12s %-30s\n",pc->data[pos].name,pc->data[pos].age,pc->data[pos].sex,pc->data[pos].tele,pc->data[pos].addr);
}

2.5 修改信息功能代码的实现

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

2.6 按名字排序信息功能代码的实现

//按照名字来排序
int cmp_by_name(const void* e1, const void* e2)
{return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}void SortContact(Contact* pc)
{qsort(pc->data, pc->sz, sizeof(PeoInfo), cmp_by_name);printf("排序成功\n");
}

3. 完整静态版本通讯录的全部源码

3.1 contact.c

#define _CRT_SECURE_NO_WARNINGS 1#include "contact.h"void InitContact(Contact* pc)
{pc->sz = 0;memset(pc->data, 0, sizeof(pc->data));
}void AddContact(Contact* pc)
{if (pc->sz == MAX){printf("通讯录已满,无法增加\n");return;}printf("请输入名字:>");scanf("%s", pc->data[pc->sz].name);printf("请输入年龄:>");scanf("%d", &(pc->data[pc->sz].age));printf("请输入性别:>");scanf("%s", pc->data[pc->sz].sex);printf("请输入电话:>");scanf("%s", pc->data[pc->sz].tele);printf("请输入地址:>");scanf("%s", pc->data[pc->sz].addr);pc->sz++;printf("添加成功\n");
}void ShowContact(const Contact* pc)
{int i = 0;//姓名      年龄      性别     电话      地址//hengchuan 20        男      123456    北京////打印标题printf("%-10s %-4s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");//打印数据for (i = 0; i < pc->sz; i++){printf("%-10s %-4d %-5s %-12s %-30s\n",pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tele, pc->data[i].addr);}
}static int FindByName(const Contact* pc, char name[])
{int i = 0;for (i = 0; i < pc->sz; i++){if (0 == strcmp(pc->data[i].name, name)){return i;}}return -1;
}void DelContact(pContact pc)
{char name[MAX_NAME] = { 0 };if (pc->sz == 0){printf("通讯录为空,无法删除\n");return;}//删除//1. 找到要删除的人 - 位置(下标)printf("输入要删除人的名字:>");scanf("%s", name);int pos = FindByName(pc, name);if (pos == -1){printf("要删除的人不存在\n");return;}int i = 0;//2. 删除 - 删除pos位置上的数据for (i = pos; i < pc->sz - 1; i++){pc->data[i] = pc->data[i + 1];}pc->sz--;printf("删除成功\n");
}void SearchContact(const Contact* pc)
{char name[MAX_NAME] = { 0 };printf("请输入要查找人的名字:>");scanf("%s", name);//查找int pos = FindByName(pc, name);if (pos == -1){printf("要查找的人不存在\n");return;}//打印printf("%-10s %-4s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");//打印数据printf("%-10s %-4d %-5s %-12s %-30s\n",pc->data[pos].name,pc->data[pos].age,pc->data[pos].sex,pc->data[pos].tele,pc->data[pos].addr);
}void ModifyContact(Contact* pc)
{char name[MAX_NAME] = { 0 };printf("请输入要修改人的名字:>");scanf("%s", name);int pos = FindByName(pc, name);if (pos == -1){printf("要修改的人不存在\n");return;}//修改printf("请输入名字:>");scanf("%s", pc->data[pos].name);printf("请输入年龄:>");scanf("%d", &(pc->data[pos].age));printf("请输入性别:>");scanf("%s", pc->data[pos].sex);printf("请输入电话:>");scanf("%s", pc->data[pos].tele);printf("请输入地址:>");scanf("%s", pc->data[pos].addr);printf("修改成功\n");
}//按照名字来排序
int cmp_by_name(const void* e1, const void* e2)
{return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}void SortContact(Contact* pc)
{qsort(pc->data, pc->sz, sizeof(PeoInfo), cmp_by_name);printf("排序成功\n");
}

3.2 contact.h

#pragma once#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>#define MAX 100
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_TELE 12
#define MAX_ADDR 30//表示一个人的信息
typedef struct PeoInfo
{char name[MAX_NAME];int age;char sex[MAX_SEX];char tele[MAX_TELE];char addr[MAX_ADDR];
}PeoInfo;//静态版本的设计
typedef struct Contact
{PeoInfo data[MAX];//存放数据int sz;//记录通讯录中的有效信息个数
}Contact, *pContact;//初始化通讯录
void InitContact(Contact* pc);//增加指定联系人
void AddContact(Contact* pc);//显示联系人信息
void ShowContact(const Contact* pc);//删除指定联系人
//void DelContact(Contact* pc);
void DelContact(pContact pc);//查找指定联系人
void SearchContact(const Contact* pc);//修改通讯录
void ModifyContact(Contact* pc);//排序通讯录元素
void SortContact(Contact* pc);

3.3 test.c

#define _CRT_SECURE_NO_WARNINGS 1
#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");
}enum Option
{EXIT,ADD,DEL,SEARCH,MODIFY,SHOW,SORT
};int main()
{int input = 0;Contact con;//通讯录//初始化通讯录//加载文件的信息到通讯录中InitContact(&con);do{menu();printf("请选择:>");scanf("%d", &input);switch (input){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 EXIT:printf("退出通讯录\n");break;default:printf("选择错误\n");break;}} while (input);return 0;
}

4. 静态版本通讯录的缺点

缺点:

  1. 通讯录的大小是固定的 - 100个元素
  2. 当通讯录退出后,重新运行,之前的信息都丢了
    当前通讯录中的信息都是保存在内存中的,程序退出,内存就回收了,下一次重新运行程序,内存重新分配,之前的数据就不见了

所以恒川之后会给大家带来动态通讯录的版本,请大家拭目以待吧!!
如果这份博客对大家有帮助,希望各位给恒川一个免费的点赞作为鼓励,并评论收藏一下,谢谢大家!!!
制作不易,如果大家有什么疑问或给恒川的意见,欢迎评论区留言。

相关文章:

【进阶C语言】静态版通讯录的实现(详细讲解+全部源码)

前言 &#x1f4d5;作者简介&#xff1a;热爱跑步的恒川&#xff0c;正在学习C/C、Java、Python等。 &#x1f4d7;本文收录于C语言进阶系列&#xff0c;本专栏主要内容为数据的存储、指针的进阶、字符串和内存函数的介绍、自定义类型结构、动态内存管理、文件操作等&#xff0…...

【JavaWeb】后端(Maven+SpringBoot+HTTP+Tomcat)

目录一、Maven1.什么是Maven?2.Maven的作用?3.介绍4.安装5.IDEA集成Maven6.IDEA创建Maven项目7.IDEA导入Maven项目8.依赖配置9.依赖传递10.依赖范围11.生命周期二、SpringBoot1.Spring2.SpringBoot3.SpringBootWeb快速入门二、HTTP1.HTTP-概述2.HTTP-请求协议3.HTTP-响应协议…...

面试官:准备了一些springboot相关的面试题,快来看看吧

文章目录摘要Spring Boot 中的注解 RestController 和 Controller 有什么区别&#xff1f;Spring Boot 中如何处理异常&#xff1f;使用 ExceptionHandler 注解处理特定类型的异常&#xff1a;使用 ExceptionHandler 注解可以将特定类型的异常映射到一个处理方法上&#xff0c;…...

原子的波尔模型、能量量子化、光电效应、光谱实验、量子态、角动量

一. 卢瑟福模型 1908年&#xff0c;卢瑟福用α粒子继续轰击金箔&#xff0c;发现有极少数粒子&#xff0c;发生了非常大的偏移。而这对于当时主流的葡萄干面包模型理论分析是相悖的。 原子可看成由带正电的原子核和围绕核运动的一些电子组成&#xff0c;原子中心的原子核带正…...

【如何使用Arduino控制WS2812B可单独寻址的LED】

【如何使用Arduino控制WS2812B可单独寻址的LED】 1. 概述2. WS2812B 发光二极管的工作原理3. Arduino 和 WS2812B LED 示例3.1 例 13.2 例 24. 使用 WS2812B LED 的交互式 LED 咖啡桌4.1 原理图4.2 源代码在本教程中,我们将学习如何使用 Arduino 控制可单独寻址的 RGB LED 或 …...

计算机基本知识扫盲(持续更)

计算机基本知识扫盲Q&#xff1a;硬盘和磁盘有什么区别&#xff1f;A&#xff1a;硬盘和磁盘都是存储数据的设备。磁盘指的是存储数据的圆形或者是方形的光盘&#xff0c;但是硬盘则是指机械式硬盘和固态硬盘。磁盘一般用于存储少量数据&#xff0c;例如软件安装文件、音乐和电…...

学习大数据需要什么语言基础

Python易学&#xff0c;人人都可以掌握&#xff0c;如果零基础入门数据开发行业的小伙伴&#xff0c;可以从Python语言入手。 Python语言简单易懂&#xff0c;适合零基础入门&#xff0c;在编程语言排名上升最快&#xff0c;能完成数据挖掘、机器学习、实时计算在内的各种大数…...

ElasticSearch——详细看看ES集群的启动流程

参考&#xff1a;一起看看ES集群的启动流程 本文主要从流程上介绍整个集群是如何启动的&#xff0c;集群状态如何从Red变成Green&#xff0c;然后分析其他模块的流程。 这里的集群启动过程指集群完全重启时的启动过程&#xff0c;期间要经历选举主节点、主分片、数据恢复等重…...

【教学类-30-01】5以内加法题不重复(一页两份)(包含1以内、2以内、3以内、4以内、5以内加法,抽取最大不重复数量)

作品样式&#xff1a; 背景需求&#xff1a; 虽然学前阶段就对幼儿训练加减法列式题遭到诟病&#xff0c;但是从不少幼儿&#xff08;特别是二胎&#xff09;在家中已经开始适应加减法题型了。 结合中班年龄特点&#xff0c;我从5以内的不重复加法题开始实验&#xff08;雪花…...

写博客8年与人生第一个502万

题记&#xff1a;我们并非生来强大&#xff0c;但依然可以不负青春。 原本想好好写一下如何制定一个目标并通过一点一滴的努力去实现&#xff0c;这三年反思发现其实写自己的经历并不重要。 很多人都听过一句话&#xff1a;榜样的力量是无穷的。 更现实和实际的情况是&#x…...

【华为OD机试真题】日志采集系统(javapython)

日志采集系统 时间限制:1s空间限制:256MB限定语言:不限 题目描述: 日志采集是运维系统的的核心组件。日志是按行生成,每行记做一条,由采集系统分 批上报。 如果上报太频繁,会对服务端造成压力;如果上报太晚,会降低用户的体验;如果一 次上报的条数太多,会导致超时…...

epoll源码剖析

文章目录1.前言2.应用层的体现3.两个重要结构(1)eventpoll(2)epitem4.四个函数(1)epoll_create源码(2)epoll_ctl源码(3)epoll_wait的源码(4)epoll_event_callback()5.水平触发和边缘触发1.状态变化2.LT模式3.ET模式1.前言 好久好久没有更新博客了&#xff0c;最近一直在实习&a…...

Linux驱动开发——高级I/O操作(一)

一个设备除了能通过读写操作来收发数据或返回、保存数据&#xff0c;还应该有很多其他的操作。比如一个串口设备还应该具备波特率获取和设置、帧格式获取和设置的操作;一个LED设备甚至不应该有读写操作&#xff0c;而应该具备点灯和灭灯的操作。硬件设备是如此众多&#xff0c;…...

适配器模式:C++设计模式中的瑞士军刀

适配器模式揭秘&#xff1a;C设计模式中的瑞士军刀引言设计模式的重要性适配器模式简介与应用场景适配器模式在现代软件设计中的地位与价值适配器模式基本概念适配器模式的定义与核心思想类适配器与对象适配器的比较设计原则与适配器模式的关系类适配器实现类适配器模式的UML图…...

【三十天精通Vue 3】 第三天 Vue 3的组件详解

✅创作者&#xff1a;陈书予 &#x1f389;个人主页&#xff1a;陈书予的个人主页 &#x1f341;陈书予的个人社区&#xff0c;欢迎你的加入: 陈书予的社区 &#x1f31f;专栏地址: 三十天精通 Vue 3 文章目录引言一、Vue 3 组件的概述1. Vue 3 的组件系统2. Vue 3 组件的特点…...

SqlServer实用系统视图,你了解多少?

SqlServer实用系统视图&#xff0c;你了解多少&#xff1f;前言master..spt_valuessysdatabasessysprocesses一套组合拳sysobjectssys.all_objectssyscolumnssystypessyscommentssysindexes结束语前言 在使用任何数据库软件的时候&#xff0c;该软件都会提供一些可能不是那么公…...

NodeJS Cluster模块基础教程

Cluster简介 默认情况下&#xff0c;Node.js不会利用所有的CPU&#xff0c;即使机器有多个CPU。一旦这个进程崩掉&#xff0c;那么整个 web 服务就崩掉了。 应用部署到多核服务器时&#xff0c;为了充分利用多核 CPU 资源一般启动多个 NodeJS 进程提供服务&#xff0c;这时就…...

[C++笔记]vector

vector vector的说明文档 vector是表示可变大小数组的序列容器(动态顺序表)。就像数组一样&#xff0c;vector也采用连续的存储空间来储存元素。这就意味着可以用下标对vector的元素进行访问&#xff0c;和数组一样高效。与数组不同的是&#xff0c;它的大小可以动态改变——…...

Python 迁移学习实用指南:1~5

原文&#xff1a;Hands-On Transfer Learning with Python 协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 本文来自【ApacheCN 深度学习 译文集】&#xff0c;采用译后编辑&#xff08;MTPE&#xff09;流程来尽可能提升效率。 不要担心自己的形象&#xff0c;只关心如…...

【CSS重点知识】属性计算的过程

✍️ 作者简介: 前端新手学习中。 &#x1f482; 作者主页: 作者主页查看更多前端教学 &#x1f393; 专栏分享&#xff1a;css重难点教学 Node.js教学 从头开始学习 ajax学习 标题什么是计算机属性确定声明值层叠冲突继承使用默认值总结什么是计算机属性 CSS属性值的计算…...

路沿模板,乐山水泥路面模板,40公分路面钢模哪里有名

打路面模板&#xff1a;乐山水泥路面的优质之选在道路建设中&#xff0c;打路面模板起着至关重要的作用。它不仅关系到路面的成型质量&#xff0c;还影响着整个工程的效率和成本。乐山地区对于道路建设的需求不断增加&#xff0c;尤其是在水泥路面的铺设方面&#xff0c;40公分…...

Z-Image-Turbo LoRA WebUI实战案例:为独立游戏开发者生成角色立绘素材

Z-Image-Turbo LoRA WebUI实战案例&#xff1a;为独立游戏开发者生成角色立绘素材 1. 项目概述与价值 作为一名独立游戏开发者&#xff0c;你是否曾经为角色立绘的设计而头疼&#xff1f;传统的美术外包成本高昂&#xff0c;自己绘制又需要专业技能。现在&#xff0c;通过Z-I…...

不止于超市:用QGIS缓冲区+叠置分析,为你的奶茶店、自习室找个好位置

从奶茶店到自习室&#xff1a;QGIS空间分析赋能小微商业选址决策 走在街头&#xff0c;你是否好奇为什么某些奶茶店总是门庭若市&#xff0c;而几步之隔的同类店铺却冷冷清清&#xff1f;商业选址从来不是简单的"地段好"三个字能概括的。对于资金有限的小微创业者来说…...

鸿蒙应用开发实战:手把手教你封装一个可复用的音乐播放器管理类(ArkTS版)

鸿蒙应用开发实战&#xff1a;构建高可复用的音乐播放器管理类&#xff08;ArkTS版&#xff09; 在鸿蒙应用开发中&#xff0c;音频播放功能是许多应用的核心需求。本文将深入探讨如何设计一个健壮、可复用的音乐播放器管理类&#xff0c;采用ArkTS语言实现&#xff0c;帮助开发…...

Youtu-VL-4B-Instruct-GGUF模型安全考量:在网络安全领域的潜在应用与风险

Youtu-VL-4B-Instruct-GGUF模型安全考量&#xff1a;在网络安全领域的潜在应用与风险 最近和几个做安全的朋友聊天&#xff0c;他们都在头疼一个问题&#xff1a;现在的网络攻击越来越“花里胡哨”了。以前可能就是一段恶意代码&#xff0c;现在呢&#xff1f;一张精心设计的钓…...

万象视界灵坛快速部署:GitLab CI流水线自动触发镜像构建与K8s滚动更新

万象视界灵坛快速部署&#xff1a;GitLab CI流水线自动触发镜像构建与K8s滚动更新 1. 项目概述 万象视界灵坛&#xff08;Omni-Vision Sanctuary&#xff09;是一款基于OpenAI CLIP技术的高级多模态智能感知平台。该平台通过创新的像素风格界面&#xff0c;将复杂的语义对齐过…...

Janus-Pro-7B效果展示:手写体/表格/多语言混合OCR识别准确率实测

Janus-Pro-7B效果展示&#xff1a;手写体/表格/多语言混合OCR识别准确率实测 1. 引言 你有没有遇到过这样的场景&#xff1f;翻出一张老照片&#xff0c;背面是长辈用钢笔写下的寄语&#xff0c;字迹有些潦草&#xff0c;想把它转成电子版保存&#xff0c;却一个字也认不出来…...

从自动驾驶到AR眼镜:聊聊PSMNet这个双目立体匹配的‘老将’现在还能怎么用

PSMNet在2024年的技术重生&#xff1a;从经典立体匹配到轻量化落地的实战指南 六年前&#xff0c;当PSMNet在CVPR 2018上首次亮相时&#xff0c;其金字塔池化模块和堆叠沙漏3D CNN架构刷新了KITTI榜单的精度记录。如今&#xff0c;在Transformer大行其道的时代&#xff0c;这个…...

『NAS』在绿联部署One API,统一管理你的所有大模型服务

点赞 关注 收藏 学会了 &#x1f4a1;整理了一个 NAS 专属玩法专栏&#xff0c;感兴趣的工友可以戳这里关注 &#x1f449; 《NAS邪修》 One API 是一个开源的接口管理与分发系统&#xff0c;它能将各种大模型的非标接口&#xff08;如 DeepSeek、Kimi、LongCat 等&#xff…...

整理‌ 主流国产AI龙虾的核心能力对比表(支持平台/部署方式/适用场景)腾讯WorkBuddy‌ ‌阿里JVS Claw 百度DuMate

根据当前的资料&#xff0c;腾讯WorkBuddy和百度的DuMate当前有一定一定量的免费额度&#xff0c;大家可以用起来&#xff01; 主流国产AI龙虾的核心能力对比表 五款主流国产AI龙虾的核心能力对比表已整理完成&#xff0c;涵盖支持平台、部署方式与适用场景三大维度&#xff…...