单链表-通讯录

目录

单链表实现

通讯录代码实现

初始化

初始化函数

添加

删除

展示

查找

修改

销毁

代码展示

main.c

text.c

text.h

list.c

list.h


和前面的通讯录实现差不多这次就是实现一个以单链表为底层的通讯录

单链表实现

数据结构:单链表-CSDN博客

通讯录代码实现

初始化

//初始化
void InitContact(contact** con) {//初始化函数initialize(con);
}

初始化函数

// 函数:initialize,用于初始化联系人指针数组con,并从文件中读取并导入联系人信息
void initialize(contact** con) {// 打开名为"Contact.txt"的文件以只读二进制模式 ("rb")FILE* fp = fopen("Contact.txt", "rb");// 检查文件是否成功打开,如果文件不存在或无法打开,则输出错误信息并返回if (fp == NULL) {perror("fopen");  // 输出错误信息return;}// 定义一个PeoInfo类型的变量info,用于存储从文件中读取的单个联系人信息PeoInfo info;// 使用while循环逐条读取文件中的联系人信息while (fread(&info, sizeof(info), 1, fp)) {  // fread函数从文件中读取指定大小的数据到info变量// 调用Tail_insertion函数将读取到的联系人信息按照尾部插入的方式添加到通讯录(链表)中Tail_insertion(con, info);}// 当所有联系人信息成功插入后,输出提示信息printf("历史记录插入成功!\n");fclose(fp);  // 在这里关闭文件
}

尾部插入函数请看我的链表博客

添加

// 函数:AddContact,用于添加新的联系人至通讯录
void AddContact(contact** con) {// 创建一个PeoInfo类型的结构体变量info,用于存储用户输入的新联系人信息PeoInfo info;// 提示用户输入新联系人的姓名,并使用scanf读取字符串printf("请输入添加联系人姓名:\n");scanf("%s", info.name);// 提示用户输入新联系人性别,并使用scanf读取字符串printf("请输入添加联系人性别:\n");scanf("%s", info.sex);// 提示用户输入新联系人年龄,并使用scanf读取整数printf("请输入添加联系人年龄:\n");scanf("%d", &info.age);// 提示用户输入新联系人电话号码,并使用scanf读取字符串printf("请输入添加联系人电话:\n");scanf("%s", info.tel);// 提示用户输入新联系人地址,并使用scanf读取字符串printf("请输入添加联系人地址:\n");scanf("%s", info.addr);// 将新获取的联系人信息通过调用Tail_insertion函数将其按尾部插入的方式添加到通讯录(链表)中Tail_insertion(con, info);// 提示用户添加联系人成功printf("添加成功\n");
}

删除

// 函数:DelContact,用于根据姓名删除联系人
void DelContact(contact** con) {// 定义一个字符数组name,用于存储用户想要删除的联系人姓名char name[NAME_MAX];// 提示用户输入要删除的联系人姓名,并使用scanf读取printf("请输入要删除人的姓名>\n");scanf("%s", name);// 调用查找函数fun_b,传入通讯录头结点的指针以及待查找姓名,寻找对应联系人contact* pos = fun_b(*con, name); // 解引用con,获取通讯录头结点// 如果查找函数返回NULL,说明没有找到该姓名对应的联系人if (pos == NULL) {printf("没找到这个name\n");return;}// 调用SLTErase函数,传入通讯录头结点指针和待删除节点的指针,执行删除操作SLTErase(con, pos);// 删除操作成功后,输出提示信息printf("已经删除此联系人\n");
}

展示

// 函数:ShowContact,用于展示通讯录中的所有联系人信息
void ShowContact(contact* con) {// 设置输出格式,依次为姓名(10个字符宽度)、性别(4个字符宽度)、年龄(4个字符宽度)、电话(15个字符宽度)和地址(20个字符宽度)printf("%-10s %-4s %-4s %15s %-20s\n", "姓名", "性别", "年龄", "电话", "地址");// 初始化指向当前联系人的指针pcur为通讯录头结点contact* pcur = con;// 当pcur不为空时,即遍历整个通讯录链表while (pcur) {// 按照预先设置的格式输出当前联系人的详细信息printf("%-10s %-4s %-4d %15s %-20s\n",pcur->data.name,pcur->data.sex,pcur->data.age,pcur->data.tel,pcur->data.addr);// 遍历完当前节点后,将pcur指向下一个联系人节点pcur = pcur->next;}
}

查找

// 函数:fun_b,用于查找通讯录中指定姓名的联系人节点
contact* fun_b(contact* con, char* p) {// 初始化指针pcur指向通讯录头结点contact* pcur = con;// 循环遍历整个通讯录链表while (pcur) {// 使用strcmp函数比较当前节点联系人的姓名与输入的姓名字符串是否相同if (strcmp(pcur->data.name, p) == 0) {// 若姓名相同,直接返回当前节点的地址return pcur; // 找到了直接返回这个节点的位置}// 若姓名不同,则将pcur指向下一个联系人节点继续比较pcur = pcur->next;}// 若遍历完整个链表都没有找到匹配的姓名,则返回NULLreturn NULL;
}

修改

// 函数:ModifyContact,用于修改通讯录中指定姓名的联系人信息
void ModifyContact(contact** con) {// 定义一个字符数组name,用于存储用户想要修改的联系人姓名char name[NAME_MAX];// 提示用户输入要修改的联系人姓名,并使用scanf读取printf("请输入要修改的人的姓名>\n");scanf("%s", name);// 调用查找函数fun_b,传入通讯录头结点的指针以及待查找姓名,寻找对应联系人contact* pos = fun_b(*con, name); // 解引用con,获取通讯录头结点// 如果查找函数返回NULL,说明没有找到该姓名对应的联系人if (pos == NULL) {printf("没找到这个name\n");return;}// 找到联系人后,提示用户并逐一输入新的联系人信息printf("找到了\n");printf("请输入修改后的联系人姓名:\n");scanf("%s", pos->data.name);printf("请输入修改后的联系人性别:\n");scanf("%s", pos->data.sex);printf("请输入修改后的联系人年龄:\n");scanf("%d", &(pos->data.age));printf("请输入修改后的联系人电话:\n");scanf("%s", pos->data.tel);printf("请输入修改后的联系人地址:\n");scanf("%s", pos->data.addr);// 此处并未显示,但在实际应用中,通常会在输入验证和更新信息后,输出修改成功的提示信息
}// 这段代码的作用是先查找通讯录中指定姓名的联系人,找到后让用户重新输入该联系人的各项信息,从而实现对联系人信息的修改。

销毁

// 函数:SaveContact,用于将通讯录数据保存到文件
void SaveContact(contact* con) {// 打开名为"Contact.txt"的文件以二进制写入模式 ("wb")FILE* pf = fopen("Contact.txt", "wb");// 检查文件是否成功打开,如果文件打开失败,则输出错误信息并返回if (pf == NULL) {perror("fopen");return;}// 遍历通讯录链表,将每个联系人的数据写入文件contact* pcur = con;while (pcur) {// 使用fwrite函数将当前联系人数据写入文件fwrite(&(pcur->data), sizeof(pcur->data), 1, pf);// 移动到下一个联系人节点pcur = pcur->next;}// 数据保存成功后输出提示信息printf("保存成功\n");fclose(pf);
}// 函数:DestroyContact,用于销毁通讯录数据结构并保存数据到文件后再清理内存
void DestroyContact(contact** con) {// 先调用SaveContact函数将当前通讯录数据保存到文件SaveContact(*con);// 调用链表销毁函数SListDesTroy,释放通讯录所占用的内存资源SListDesTroy(con);
}

代码展示

main.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"text.h"#if 0
void text1() {//创建4个节点SLTNode* a1 = (SLTNode*)malloc(sizeof(SLTNode));a1->data = 1;SLTNode* a2 = (SLTNode*)malloc(sizeof(SLTNode));a2->data = 2;SLTNode* a3 = (SLTNode*)malloc(sizeof(SLTNode));a3->data = 3;SLTNode* a4 = (SLTNode*)malloc(sizeof(SLTNode));a4->data = 4;//链接节点a1->next = a2;a2->next = a3;a3->next = a4;    a4->next = NULL;SLTNode* ptr = a1;SLTPrint(ptr);
}void text2() {SLTNode* a1 = NULL;Tail_insertion(&a1,1);Tail_insertion(&a1,2);Tail_insertion(&a1,3);Tail_insertion(&a1,4);SLTPrint(&a1);SListDesTroy(&a1);SLTPrint(&a1);/*Head_insertion(&a1,0);SLTPrint(&a1);*//*Tail_delete(&a1);SLTPrint(&a1);*//*Head_delete(&a1);SLTPrint(&a1);*///SLTNode *p = Find(a1, 1);//SLTInsert(&a1, p, 5);//SLTPrint(&a1);/*SLTInsert(&a1, 1, 5);SLTPrint(&a1);*//*SLTInsertAfter(p,6);SLTPrint(&a1);*///if (p == NULL)//{//	printf("NO");//}//else//{//	printf("YES");//}/*SLTErase(&a1,p);SLTPrint(&a1);*//*SLTEraseAfter(p);SLTPrint(&a1);*/
}
int main() {//text1();text2();return 0;
}
#endif // 0
void eumn() {printf("****************************\n");printf("****1.add  2.DEL  3.FIND****\n");printf("****4.MOD  5.SHOW 6.SORT****\n");printf("****7.SAVE        0.EXIT****\n");printf("****************************\n");
}
int main() {contact* con = NULL;//创建一个为NULL的链表int input = -1;InitContact(&con);//初始化do{eumn();printf("请选择您的操作:\n");scanf("%d", &input);switch (input){case ADD:AddContact(&con);break;case DEL:DelContact(&con);break;case FIND:FindContact(con);break;case MOD:ModifyContact(&con);break;case SHOW:ShowContact(con);break;case SORT:Contacts_sort(con);break;case SAVE:DestroyContact(&con);break;case EXIT:break;default:printf("选择错误,请重新选择\n");break;}} while (input);return 0;
}

text.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"text.h"
#include"list.h"
//开辟内存函数
static SLTNode* SList_ina(SLTDataType x) {//申请空间SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));//判断是否为空if (newnode == NULL){perror("malloc");exit(EXIT_FAILURE);//中止程序}newnode->data = x;//将新节点的内容x赋值newnode->next = NULL;//将指向下一个地址设NULLreturn newnode;//返回节点
}
#if 0
//打印
void SLTPrint(SLTNode** Phead) {assert(Phead);SLTNode* pcur = *Phead;while (pcur){printf("%d->", pcur->data);//打印节点内容pcur = pcur->next;//下一个节点地址赋值(循环)}printf("NULL\n");
}
#endif // 0//尾插
void Tail_insertion(SLTNode** Phead, SLTDataType x){//判断链表是否为空//开辟新的节点SLTNode* newnode = SList_ina(x);if (*Phead == NULL){*Phead = newnode;}else{//用一个指针指向第一个元素SLTNode* pcur = *Phead;while (pcur->next){pcur = pcur->next;}pcur->next = newnode;}
}//头插
void  Head_insertion(SLTNode** Phead, SLTDataType x) {//创建新的节点SLTNode* newcode = SList_ina(x);//将新开辟的节点的执政指向第一个节点newcode->next = *Phead;//由于Phead指向的是头部,然后我们在头部插入了一个节点,这个时候Phead指向的就不再是头部,我们直接将新节点的地址赋值给这个指向头部的指针*Phead = newcode;
}//尾删
void Tail_delete(SLTNode** Phead) {assert(Phead && *Phead);//判断是否是一个节点//如果是就直接释放掉//如果不是就找的尾节点,和为节点的上一个节点if ((*Phead)->next == NULL)//->优先级高于*{free(*Phead);*Phead = NULL;}else{//定义两个指针都指向头节点SLTNode* Tail_1 = *Phead;SLTNode* Tail_2 = *Phead;//当Tail_1 == NULL的时候我们的while循环就跳出去了,这样我们的Tail_2就存的尾节点的上一个位置while (Tail_1 ->next){Tail_2 = Tail_1;//存储尾节点的上一个位置Tail_1 = Tail_1->next;//找尾节点}free(Tail_1);Tail_1 = NULL;Tail_2->next = NULL;//要将指向的下一个元素设为NULL}
}//头删
void Head_delete(SLTNode** Phead) {assert(*Phead && Phead);//Phead -- 不能解引用空指针  *Phead -- 指向第一个节点的指针,第一个节点不能为空//存储第二个节点的地址SLTNode* next = (*Phead)->next;//直接释放掉第一个节点free(*Phead);//将我们存储的第二个的地址赋给*Phead(头指针),让他指向第二个节点,让第二个节点变成第二个节点*Phead = next;
}#if 0//查找
SLTNode *Find(SLTNode* Phead, SLTDataType x) {assert(Phead);SLTNode* pcur = Phead;//不改变我们的头,找个小弟帮他走	while (pcur){if (pcur->data == x) {return pcur;}//往后找pcur = pcur->next;}return NULL;
}#endif // 0#if 0//在指定位置之前插⼊数据 
void SLTInsert(SLTNode** Phead, SLTNode* pos, SLTDataType x) {assert(Phead && *Phead);SLTNode* pcur = *Phead;//把第一个节点地址传给pcurSLTNode* newnode = SList_ina(x);SLTNode* poss =  Find(*Phead,pos);if (*Phead == poss){Head_insertion(Phead,x);}else{//寻找pos前的一个点while (pcur->next != poss){assert(pcur->next);//判断下一个节点不能为空pcur = pcur->next;}//改变节点指针newnode->next = poss;pcur->next = newnode;}
}
#endif // 0//在指定位置之后插⼊数据 
void SLTInsertAfter(SLTNode* pos, SLTDataType x) {assert(pos && pos->next);SLTNode* newnode = SList_ina(x);SLTNode* pcur = pos->next;//将下一个节点地址给pcurnewnode->next = pcur;pos->next = newnode;
}//删除pos节点 
void SLTErase(SLTNode** Phead, SLTNode* pos) {assert(Phead && *Phead);if (*Phead == pos)//要删除第一个节点{//直接调用头删除Head_delete(Phead);}else{//将第一个节点地址传入pcurSLTNode* pcur = *Phead;while (pcur->next != pos){pcur = pcur->next;}pcur->next = pos->next;//将pos中next指针指向的地址让pcur中next指针指向//释放posfree(pos);pos = NULL;}
}//删除pos之后的节点 
void SLTEraseAfter(SLTNode* pos){assert(pos && pos->next);SLTNode* pcur = pos->next;//将第二个节点的地址存在pcurpos->next = pcur->next;//这边pcur->next指向的是第三个节点的地址free(pcur);pcur = NULL;
}//销毁链表
void SListDesTroy(SLTNode** Phead) {//这里的销毁我们需要将每一个节点都销毁掉assert(Phead && *Phead);SLTNode* pcur = *Phead;while (pcur){SLTNode* next = pcur->next;//将下一个位置存储一下free(pcur);pcur = next;}*Phead = NULL;
}

text.h

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>
//#include<vld.h>
#include"list.h"typedef struct PersonInfo SLTDataType;
//定义链表节点结构
typedef struct SListNode
{SLTDataType data;//内容struct SListNode* next;//指向下一个节点的指针
}SLTNode;//打印
void SLTPrint(SLTNode** Phead);//尾部插入/头部插入
void Tail_insertion(SLTNode** Phead, SLTDataType x);
void  Head_insertion(SLTNode** Phead, SLTDataType x);//尾部删除/头部删除
void Tail_delete(SLTNode** Phead);
void Head_delete(SLTNode** Phead);//查找
SLTNode* Find(SLTNode* Phead, SLTDataType x);//在指定位置之前插⼊数据 
void SLTInsert(SLTNode** Phead, SLTNode* pos, SLTDataType x);
//在指定位置之后插⼊数据 
void SLTInsertAfter(SLTNode* pos, SLTDataType x);//删除pos节点 
void SLTErase(SLTNode** Phead, SLTNode* pos);
//删除pos之后的节点 
void SLTEraseAfter(SLTNode* pos);
//销毁链表 
void SListDesTroy(SLTNode** Phead);

list.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"text.h"
#include"list.h"
void initialize(contact** con) {//读文件内容FILE* fp = fopen("Contact.txt", "rb");if (fp == NULL) {perror("fopen");return;}//创建一个通讯录结构PeoInfo info;//利用while循环进行导入while (fread(&info,sizeof(info),1,fp)){Tail_insertion(con,info);//尾插}fclose(fp);printf("历史记录插入成功!\n");}//初始化
void InitContact(contact** con) {//初始化函数initialize(con);
}//增加
void AddContact(contact** con){//创建一个通讯录结构PeoInfo info;printf("请输入添加联系人姓名:\n");scanf("%s", &info.name);printf("请输入添加联系人性别:\n");scanf("%s", &info.sex);printf("请输入添加联系人年龄:\n");scanf("%d", &info.age);printf("请输入添加联系人电话:\n");scanf("%s", &info.tel);printf("请输入添加联系人地址:\n");scanf("%s", &info.addr);//进行尾插Tail_insertion(con, info);printf("添加成功\n");
}//展示
void ShowContact(contact* con) {printf("%-10s %-4s %-4s %15s %-20s\n", "姓名", "性别", "年龄", "电话", "地址");contact* pcur = con;while (pcur){printf("%-10s %-4s %-4d %15s %-20s\n",pcur->data.name,pcur->data.sex,pcur->data.age,pcur->data.tel,pcur->data.addr);pcur = pcur->next;//每打印一个节点走向下一个节点}
}//查找函数
contact* fun_b(contact* con,char *p) {contact* pcur = con;while (pcur){if (strcmp(pcur->data.name, p) == 0) {return pcur;//找到了直接返回这个节点的位置}pcur = pcur->next;}return NULL;
}//删除
void DelContact(contact** con) {char name[NAME_MAX];printf("请输入要删除人的姓名>\n");scanf("%s", name);//查找函数contact* pos = fun_b(*con, name);//解引用conif (pos == NULL)	{printf("没找到这个name\n");return;}
SLTErase(con, pos);
printf("已经删除此联系人\n");}//查找
void FindContact(contact* con) {char name[NAME_MAX];printf("请输入要查找人的姓名>\n");scanf("%s", name);//查找函数contact* pos = fun_b(con, name);if (pos == NULL){printf("没找到这个name");return;}printf("找到了\n");printf("%-10s %-4s %-4d %15s %-20s\n",pos->data.name,pos->data.sex,pos->data.age,pos->data.tel,pos->data.addr);
}//修改通讯录数据
void ModifyContact(contact** con) {char name[NAME_MAX];printf("请输入要修改的人的姓名>\n");scanf("%s", name);//查找函数contact* pos = fun_b(*con, name);//解引用conif (pos == NULL){printf("没找到这个name");return;}printf("找到了\n");printf("请输入添加联系人姓名:\n");scanf("%s", pos->data.name);printf("请输入添加联系人性别:\n");scanf("%s", pos->data.sex);printf("请输入添加联系人年龄:\n");scanf("%d", &(pos->data.age));printf("请输入添加联系人电话:\n");scanf("%s", pos->data.tel);printf("请输入添加联系人地址:\n");scanf("%s", pos->data.addr);
}int compareMyType_name(const void* a1, const void* a2) {return strcmp(((PeoInfo*)a1)->name, ((PeoInfo*)a2)->name);
}void compareMyType_age(void* a1, void* a2) {return ((PeoInfo*)a1)->age - ((PeoInfo*)a2)->age;
}
//排序//销毁之前的存储
void SaveContact(contact* con) {FILE* pf = fopen("Contact.txt","wb");if (pf == NULL){perror("fopen");return;}//将通讯录数据写⼊⽂件 contact* pcur = con;while (pcur){fwrite(&(pcur->data),sizeof(pcur->data),1,pf);pcur = pcur->next;//一直往后走}printf("保存成功\n");
}
//销毁
void DestroyContact(contact** con) {SaveContact(*con);//存储SListDesTroy(con);//直接调用链表中的销毁
}

list.h

#pragma once#pragma once
#define NAME_MAX 100
#define SEX_MAX 4
#define TEL_MAX 11
#define ADDR_MAX 100enum MyEnum
{EXIT,ADD,//增加DEL,//删除FIND,//查找MOD,//修改SHOW,//展示SORT,//排序SAVE,//保存
};//前置声明
typedef struct SListNode contact;//用户数据
typedef struct PersonInfo
{char name[NAME_MAX];char sex[SEX_MAX];int age;char tel[TEL_MAX];char addr[ADDR_MAX];
}PeoInfo;//初始化通讯录
void InitContact(contact** con);
//添加通讯录数据
void AddContact(contact** con);
//删除通讯录数据
void DelContact(contact** con);
//展示通讯录数据
void ShowContact(contact* con);
//查找通讯录数据
void FindContact(contact* con);
//修改通讯录数据
void ModifyContact(contact** con);
//销毁通讯录数据
void DestroyContact(contact** con);
//排序
//void Contacts_sort(contact* con);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/630444.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Springboot+Vue项目-基于Java+MySQL的高校心理教育辅导系统(附源码+演示视频+LW)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &…

现在给政府机关医院学校部队供货的方式有哪些?

给政府机关、医院、学校和部队供货的方式主要包括以下几种&#xff1a; 直接采购&#xff1a;政府机关、医院、学校和部队通过招标或直接与供应商进行谈判&#xff0c;确定采购的产品和价格。这种方式常见于大宗或重要物资的采购&#xff0c;能够确保采购过程的透明度和公正性…

【笔试强训】双指针的思想!

1.数组中字符串的最小距离 题目链接 解题思路&#xff1a; 小技巧 ✌&#xff1a;标记两个字符串是否被找到&#xff0c;每次找到一个字符串就更新一次答案来保证找到的是最小距离。 实现代码&#xff1a; #include <iostream> using namespace std;int main() {in…

阿斯利康、赫力昂、京东健康、宝洁等行业大咖齐聚2024中国消费者健康数字创新峰会

随着健康中国2030战略规划不断推进&#xff0c;消费者健康市场发展也日趋强劲&#xff0c;体现出健康消费意识提前&#xff0c;自我健康管理意识增强的局面。后疫情时代下&#xff0c;消费者健康市场呈现出卓越的韧性与活力。 由ECV International倾力打造的2024中国消费者健康…

微服务之CircuitBreaker断路器

一、概述 1.1背景 在一个分布式系统中&#xff0c;每个服务都可能会调用其它的服务器&#xff0c;服务之间是相互调用相互依赖。假如微服务A调用微服务B和微服务C&#xff0c;微服务B和微服务C又调用其他的微服务。这就是构成所谓“扇出”。 如果扇出的链路上某个微服务的调…

Goland远程连接Linux进行项目开发

文章目录 1、Linux上安装go的环境&#xff12;、配置远程连接3、其他配置入口 跑新项目&#xff0c;有个confluent-Kafka-go的依赖在Windows上编译不通过&#xff0c;报错信息&#xff1a; undefined reference to __imp__xxx似乎是这个依赖在Windows上不支持&#xff0c;选择让…

MES给制造业带来看得见的效益

作为连接生产控制系统和企业管理系统的纽带&#xff0c;MES为企业提供实时生产数据&#xff0c;帮助企业进行更加明智的决策&#xff0c;并实时调整生产管理&#xff0c;最终降低运营成本、提高运营利润和资产利用率、保证生产安全与合规。 MES主要功能包括工艺技术管理、生产…

Tomcat和Spring Boot配置https

生成测试证书 生成证书前&#xff0c;先验证本地是否正确配置jdk环境变量&#xff0c;如果jdk环境变量配置正确&#xff0c;在命令行程序输入生成证书的命令。 keytool -genkey -alias tomcat -keyalg RSA -keystore "F:\job\apache-tomcat-8.5.29\key\freeHttps.keysto…

如何使用WinSCP通过固定公网TCP地址实现远程连接内网设备传输文件

文章目录 1. 简介2. 软件下载安装&#xff1a;3. SSH链接服务器4. WinSCP使用公网TCP地址链接本地服务器5. WinSCP使用固定公网TCP地址访问服务器 1. 简介 ​ Winscp是一个支持SSH(Secure SHell)的可视化SCP(Secure Copy)文件传输软件&#xff0c;它的主要功能是在本地与远程计…

SAP HCM 离职是1号 正确计算免税金额

员工是1号离职&#xff0c;如何正确计算个税中的免税金额&#xff0c;例如员工2024年3月1日离职&#xff0c;现在计算2月的工资&#xff0c;因为是下发薪所以&#xff0c;12月、1月、2月是三个月&#xff0c;3*500015000&#xff0c;但是系统计只有10000. 如果要计算出三个月&a…

合并区间详解

题目&#xff1a; 大体思路&#xff1a; 先排序&#xff0c;设置一个新数组&#xff0c;将原数组遍历的第一位添加到新数组&#xff0c;之后不断的将遍历原数组后的起始位置和新数组的终止位置进行比较&#xff0c;大于&#xff0c;则添加到新数组&#xff0c;不大于&#xff…

2024年Q1季度冰箱行业线上市场销售数据分析

Q1季度冰箱线上市场表现不如预期。 根据鲸参谋数据显示&#xff0c;2024年1月至3月线上电商平台&#xff08;京东天猫淘宝&#xff09;冰箱累计销量约410万件&#xff0c;环比下降11%&#xff0c;同比下降21%&#xff1b;累计销售额约98亿元&#xff0c;环比下降31%&#xff0…