C语言排序 十万火急! 想按照名字将通讯录排序,但是我现在写不下去了,下面该怎么写啊? 下面应该

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言排序 十万火急! 想按照名字将通讯录排序,但是我现在写不下去了,下面该怎么写啊? 下面应该相关的知识,希望对你有一定的参考价值。

C语言排序 十万火急!
想按照名字将通讯录排序,但是我现在写不下去了,下面该怎么写啊?
下面应该是把这些信息弄到文件里吧?

这很简单,只是你那个sort函数写乱了。如果你的记录是链表,排序交换略复杂些;若是数组,你那个选择sort的基本结构就可以。下面给你提供一个作参考:

void sort(struct Man *p,int n)//p是数组第一元素指针,n是数组长度
    int i,j,k;
    struct Man t;
    for(i=0;i<n;i++)
        for(k=i,j=k+1;j<n;j++)
            if(strcmp(p[k].Name,p[j].Name)>0)
                k=j;
        if(k!=i)//这里是k与i的关系而非j
            t=p[k];//这里交换整个数组元素,不能只交换成员Name
            p[k]=p[i];
            p[i]=t;
        
    
追问

你好 请问你知道这是怎么错的吗

我的Save函数是这样的

我是这样用的

这是在另一个函数里调用的

追答

你能不能一个问题一个问题解决?排序问题解决了吗?如果解决了,我提供的代码你也看懂了,特别是注释你也理解了,那后面就不会出图片上的问题了!你那个错误提示先说Save没有声明,接着又说Save重复定义,所以代码不全搞不清怎么回事。但有一点是明显的,pMan->Name这样使用指针,说明pMan是指向一个Man变量的,但指向一个独立的Man变量的指针怎么可以用++操作?所以感觉指针用得很乱,也没有看到pMan到底指向了谁……

参考技术A 一眼就看到错误了 temp应该是个数组
char temp[8];才对追问

请问下面该怎么写?

我这样写错了好多

黑色部分不能这样写吗?

参考技术B

怎么发你,咋个俩系你?

2458194647

c语言 通讯录系统 增删改查 排序 动态内存开辟及文件保存与读取

c语言 通讯录系统 动态内存开辟及文件的保存与读取


一个最基本的通讯录系统,我们要实现的基本功能包括增删改查,并要在此基础上然后在对其进行各种扩充,比如排序,以及动态开辟内存进行存储,还有实现通讯录的文件保存和从文件中将已存的联系人加载并展示出来等等。
因为我太ben了,这里就不一一给大家解释了,不过代码上大概都有相应的注释,大家参考,有错误的地方要及时给我指出啊,我这么笨的写完都很不容易了,不多说,直接上代码.

对其进行分析,我们需要以下三个不同文件

Contact.h 声明函数

#define _CRT_SECURE_NO_WARNINGS 1
#define DEFAULT_SZ 5	//初始动态开辟五个数据的空间

#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_PHONE 16
#define MAX_ADDR 30
#include <stdio.h>
#include <string.h>
#include<stdlib.h>
#include<errno.h>
enum OP_ENUM    //避免魔鬼数字的出现

	QUIT,	//停止
	ADD,	//增加
	DEL,	//删除
	SEEK,	//查找
	ALTER,	//修改
	SHOW,	//显示
	DELALL,	//删除所有联系人
	SORT,	//排序
	SAVE,	//保存文件
;
typedef struct Info

	char name[MAX_NAME];
	char sex[MAX_SEX];
	int age;
	char phone[MAX_PHONE];
	char addr[MAX_ADDR];
Info;
//通讯录类型
typedef struct Contact

	struct Info *data;	//存放信息
	int size;	//记录当前已经有的元素个数
	int capacity;	//当前通讯录的最大容量
Contact;
//声明函数
void InitContact(Contact *ps);//初始化通讯录
void addpeo(Contact *ps);//增加一个联系人信息
void showpeo(const Contact *ps);//打印所有联系人信息
//int findname(struct Contact *ps, char name[MAX_NAME]);//查找函数,根据姓名查找
void delpeo(Contact *ps);//调用查找函数删除指定联系人信息
void seekpeo(Contact *ps); //调用查找函数查找指定联系人信息
void alterpeo(Contact *ps); ///调用查找函数修改指定联系人信息
void sortpeo(Contact *ps);  //排序通讯录联系人信息
void delall(Contact *ps); //删除所有联系人
void sortpeo(Contact *ps);	//对联系人信息进行排序
void savepeo(Contact *ps);	//保存数据到文件中
void LoadContact(Contact *ps);	//加载文件中的信息至通讯录

Contact.c 实现函数的具体功能

这里要实现我们具体函数的功能,所以我们来定义一个Contact.c文件

Contact.c

#define _CRT_SECURE_NO_WARNINGS 1
#include<assert.h>
#include"contact.h"


void LoadContact(Contact *ps);

// 1.查找联系人的位置, static 表示只能在本程序内部使用
static int findname(const Contact *ps, char name[MAX_NAME])

	int i = 0;
	for (i = 0; i < ps->size; i++)
	
		if (0 == strcmp(ps->data[i].name, name))
		
			return i;
		
	
	return -1;//找不到返回-1


void InitContact(Contact *ps)

	ps->data = (struct Info*)malloc(DEFAULT_SZ * sizeof(Info));
	if (ps->data == NULL)
	
		return;
	
	ps->size = 0;
	ps->capacity = DEFAULT_SZ;
	//把文件中已经存放的数据读取至通讯录中
	LoadContact(ps);


void CheckCapacity(Contact *ps)

	assert(ps != NULL);
	if (ps->size == ps->capacity)
	
		//增容
		struct Info* ptr = realloc(ps->data, (ps->capacity + 5)*sizeof(Info));
		if (ptr != NULL)
		
			ps->data = ptr;
			ps->capacity += 5;
			printf("增容成功!\\n");
		
		else
		
			printf("增容失败!\\n");
		
	


void LoadContact(Contact *ps)

	Info tmp =  0 ;	//定义一个临时的空间来存放文件中读取的数据
	FILE* pfread = fopen("contact.txt", "rb");
	if (pfread == NULL)
	
		printf("%s\\n", strerror(errno));
		return;
	
	//读取文件至通讯录中
	while ((fread(&tmp, sizeof(Info), 1, pfread)) == 1)
	
		CheckCapacity(ps);
		ps->data[ps->size] = tmp;
		ps->size++;
	
	fclose(pfread);
	pfread = NULL;


void addpeo(Contact *ps)

	assert(ps != NULL);
	//检测当前通讯录容量
	//容量已满就增容,反之则不用理会
	CheckCapacity(ps);
	//增加数据
	printf("请输入联系人姓名:");
	scanf("%s", ps->data[ps->size].name);
	printf("请输入联系人性别:");
	scanf("%s", ps->data[ps->size].sex);
	printf("请输入联系人年龄:");
	scanf("%d", &(ps->data[ps->size].age));
	printf("请输入联系人电话:");
	scanf("%s", ps->data[ps->size].phone);
	printf("请输入联系人地址:");
	scanf("%s", ps->data[ps->size].addr);
	ps->size++;
	printf("添加成功\\n");


void showpeo(const Contact *ps)

	if (ps->size == 0)
	
		printf("通讯录为空\\n");
	
	else
	
		//打印标题
		printf("%-20s\\t%-5s\\t%-3s\\t%-16s\\t%-30s\\n", "姓名", "性别", "年龄", "电话", "地址");
		for (int i = 0; i < ps->size; i++)
		

			//打印数据
			printf("%-20s\\t%-5s\\t%-3d\\t%-16s\\t%-30s\\n",
				ps->data[i].name,
				ps->data[i].sex,
				ps->data[i].age,
				ps->data[i].phone,
				ps->data[i].addr);
		
	


void delpeo(Contact *ps)

	printf("请输入要删除的联系人姓名:");
	char name[MAX_NAME];
	scanf("%s", name);
	//找到返回姓名所在元素下标,   找不到返回-1
	int pos = findname(ps, name);
	//2.删除
	if (pos == -1)
	
		printf("要删除的人不存在.\\n");
	
	else
	
		//删除数据
		int j = 0;
		for (j = pos; j <ps->size - 1; j++)
		
			ps->data[j] = ps->data[j + 1];
		
		ps->size--;
		printf("删除成功\\n");
	


void seekpeo(Contact *ps)

	char name[MAX_NAME];
	printf("请输入要查找人的姓名:");
	scanf("%s", name);
	int pos = findname(ps, name);
	if (pos == -1)
	
		printf("查无此人.\\n");
	
	else
	
		printf("%-20s\\t%-5s\\t%-3s\\t%-16s\\t%-30s\\n", "姓名", "性别", "年龄", "电话", "地址");
		//打印数据
		printf("%-20s\\t%-5s\\t%-3d\\t%-16s\\t%-30s\\n",
			ps->data[pos].name,
			ps->data[pos].sex,
			ps->data[pos].age,
			ps->data[pos].phone,
			ps->data[pos].addr);
	


void alterpeo(Contact *ps)

	char name[MAX_NAME];
	printf("请输入要修改人的姓名:");
	scanf("%s", name);
	int pos = findname(ps, name);
	if (pos == -1)
	
		printf("要修改的人不存在.\\n");
	
	else
	
		printf("请输入联系人姓名:");
		scanf("%s", ps->data[pos].name);
		printf("请输入联系人性别:");
		scanf("%s", ps->data[pos].sex);
		printf("请输入联系人年龄:");
		scanf("%d", &(ps->data[pos].age));
		printf("请输入联系人电话:");
		scanf("%s", ps->data[pos].phone);
		printf("请输入联系人地址:");
		scanf("%s", ps->data[pos].addr);
		printf("修改完成\\n");
	


void delall(Contact *ps)

	free(ps->data);	//删除所有人的的性质等同于释放data空间
	ps->data = NULL;


void sortpeo(Contact *ps)

	//此处使用冒泡排序,也可以使用快排
	//这里也只是对其进行了简单排序,如果名字相同也可以对比年龄性别等进行二次排序,具体实现方案我也就不一一列举了
	for (int i = 0; i < ps->size -1; i++)	
	
		for (int j = 0; j < ps->size - 1 - i; j++)	
		
			if (strcmp(ps->data[j].name, ps->data[j + 1].name) > 0)
			
				Info temp = ps->data[j];
				ps->data[j] = ps->data[j + 1];
				ps->data[j + 1] = temp;
			
		
	
	printf("%-20s\\t%-5s\\t%-3s\\t%-16s\\t%-30s\\n", "姓名", "性别", "年龄", "电话", "地址");
	for (int i = 0; i < ps->size; i++)
	

		//打印数据
		printf("%-20s\\t%-5s\\t%-3d\\t%-16s\\t%-30s\\n",
			ps->data[i].name,
			ps->data[i].sex,
			ps->data[i].age,
			ps->data[i].phone,
			ps->data[i].addr);
	


void savepeo(Contact *ps)

	FILE* pfwrite = fopen("contact.txt", "wb");
	if (pfwrite == NULL)
	
		printf("%s\\n", strerror(errno));
		return;
	
	//将通讯录中的数据写入文件
	for (int i = 0; i < ps->size; i++)
	
		fwrite(&(ps->data[i]), sizeof(Info), 1, pfwrite);
	
	fclose(pfwrite);
	pfwrite = NULL;

test.c 进行测试

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <Windows.h>
#include<assert.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("  *  7.按名字进行排序      \\n");
	printf("  *  8.保存信息到文件      \\n");
	printf("  *  0.退出                \\n");
	printf("***************************\\n");


//
//1.此处由于showpeo()函数的形参与其他函数参数类型有所不同,所以在此使用转移表会出现warning警告
//2.其内部函数类型为void,但此处定义为void*与其不兼容也会出现warning警告
//void *(*Contact_table[])(Contact *) =  NULL, addpeo, delpeo, seekpeo, alterpeo, showpeo, delall, sortpeo, savepeo ;//转移表
//
int main()

	int select = 1;
	Contact con;	//con就是通讯录,里面包含n(不确定要录入多少个,所以用n代替) 个元素的数据和size和capacity
	//初始化通讯录,
	InitContact(&con);//结构体传参,传址调用
	while (select)
	
		menu();
		printf("请选择:");
		scanf("%d", &select);
		//void *tmp = Contact_table[select](&con);
		switch (select)
		
		case ADD:
			addpeo(&con);
			break;
		case DEL:
			delpeo(&con);
			break;
		case SEEK:
			seekpeo(&con);
			break;
		case ALTER:
			alterpeo(&con);
			break;
		case SHOW:
			showpeo(&con);
			break;
		case DELALL:			
			delall(&con);//销毁通讯录——释放动态开辟的内存
			break;
		case SORT:
			sortpeo(&con);
			break;
		case SAVE:
			savepeo(&con);
			break;
		case QUIT:
			savepeo(&con);//退出之前也可以先执行savepeo函数保存数据,避免忘记保存而出现差错
			printf("谢谢使用!\\n");
			break;
		default:
			printf("选择错误!\\n");
			break;
		
	
	system("pause");
	return 0;

码完这么多字已经到了凌晨一点多了,期间我回顾了很多小的知识点,不过运用的程度连熟悉可能都算不上,最多可能也只是了解,可现在是并不代表以后也是,我还是会好好努力,加油,奥里给。

努力活成别人的信仰,共勉!

以上是关于C语言排序 十万火急! 想按照名字将通讯录排序,但是我现在写不下去了,下面该怎么写啊? 下面应该的主要内容,如果未能解决你的问题,请参考以下文章

苹果6通讯录怎么按字母顺序排列

c语言程序:输入人名和电话号码然后按照人名字母表顺序对通讯录排序,代码如下输入内容后回车无法运行?

c语言用数组做通讯录 怎样将联系人的姓名首字母排序 并且输出 求大侠

C语言进阶通讯录(静态/动态)

c语言通讯录管理系统的排序怎么做?

c语言通讯录排序按年龄从小到大输出