[C语言]实现终端输入任意字符串转十六进制,并保存到文件; 将输入的字符串按照每个节点当做属性值创建链表,链表可遍历查询;用快速排序对上面链表数据进行排序

我的实现大概流程:

1)首先用fopen()打开文件,输入任意字符串,然后把字符串的每个字符当成一个节点存入链表;

2)把字符串转换成十六进制数据格式,保存到一个char数组里面,再用fwrite()写入到文件中;

3)然后用快速排序对链表的数据进行排序,打印出来。

具体函数实现看代码。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>


/*
	1、实现终端输入任意字符串转十六进制,并保存到文件;
	   将输入的字符串按照每个节点当做属性值创建链表,链表可遍历查询
	2、用快速排序对上面链表数据进行排序
*/

//链表节点
typedef struct Node
{
	char data;//数据域
	struct Node * next;//指针域,保存逻辑上的下一个
}Node;


//插入节点到链表
Node * Add_Node(Node * head , char * str)
{
	int n = strlen(str);//字符串字符个数

	Node * p = head;
	while(p != NULL && p->next != NULL)//让p走到最后一个节点位置
	{
		p = p->next;
	}

	Node * tail = p;//链表尾节点
	Node * pnew = NULL;//指向新创建的节点

	for(int i = 0;i < n;i++)	//把字符串每一个字符作为一个节点存入链表
	{
		//把数据写入新创建节点
		pnew = (Node *)malloc(sizeof(Node));
		pnew->data = str[i];
		pnew->next = NULL;

		//把新节点存入链表
		if(head == NULL)	//从无到有
		{
			head = pnew;
			tail = pnew;
		}
		else 				//从多到少
		{
			//尾插
			tail->next = pnew;
			tail = pnew;
		}
	}
	
	return head;//返回链表首节点的地址
}


//打印链表
void print_list(Node * head)
{
	Node * p = head;
	while(p)
	{
		printf("%c ",p->data);
		p = p->next;
	}
	putchar('\n');
}


//销毁链表,防止内存泄漏
void Destroy_list(Node * head)
{
	Node * p = head;
	while(p)
	{
		//把节点一个个摘下来 free
		head = head->next;
		p->next = NULL;
		free(p);
		p = head;
	}
}


//求链表元素个数
int Elem_num(Node * head)
{
	int count = 0;

	Node * p = head;
	while(p)
	{
		count++;
		p = p->next;
	}

	return count;
}


//根据下标访问链表对应下标的元素 下标从 0 开始
char * Find_data_addr(Node * head,int index)
{
	if(head == NULL)
	{
		printf("List is NULL\n");
		return NULL;
	}
	
	Node * p = head;
	while(index-- && p != NULL)
	{
		p = p->next;//
	}

	if(p == NULL)
	{
		printf("index is error\n");
		return NULL;
	}

	return &(p->data);//返回地址
}


/*	
	quick_sort : 对链表数据快速排序
	@head : 待排序链表
	@left : 待排序序列的第一个元素
	@right : 待排序序列的最后一个元素

*/
Node * quick_sort(Node * head , int left , int right)
{
	if(left >= right)	//退出递归
	{
		return head;
	}
	
	char piv = *Find_data_addr(head, left);//基准值

	int l = left;
	int r = right;//索引

	while(l < r)
	{
		while(l < r && *Find_data_addr(head, r) >= piv)//索引r往左走找比基准值小的元素
		{
			r--;
		}
		if(l < r)
		{
			*Find_data_addr(head, l) = *Find_data_addr(head, r);//交换
		}

		while(l < r && *Find_data_addr(head, l) < piv)//索引l往右走找比基准值大的元素
		{
			l++;
		}
		if(l < r)
		{
			*Find_data_addr(head, r) = *Find_data_addr(head, l);
		}

		if(l >= r)	//找完了,r的位置就是基准值待插入的位置
		{
			*Find_data_addr(head, r) = piv;
		}
	}
	
	//一轮快排之后,序列[left,r-1] 的所有元素都比基准值小,[r+1,right] 都比基准值大
	quick_sort(head, left, r - 1);
	quick_sort(head, r + 1, right);
}


//字符串转十六进制
void str_to_hex(char *str,int str_len,char *save,int save_len)
{
	int ch1,ch2;
	int i;

	for(i = 0;i < str_len;i++)
	{
		ch1 = (str[i] & 0xf0) >> 4;//取高位
		ch2 = str[i] & 0x0f;

		//数字转字符
		ch1 += ch1 > 9 ? 0x57 : 0x30;
		ch2 += ch2 > 9 ? 0x57 : 0x30;

		save[2 * i] = ch1;
		save[2 * i + 1] = ch2;
	}
}


FILE * fopen_file()
{
	char filename[] = "hex.txt";
	FILE * fp = fopen(filename , "a+");//读写打开,文件不存在,则创建
										//文件存在,打开后,原始读的位置在文件开头,原始写的位置在文件末尾
	if(fp == NULL)
	{
		printf("fopen error!\n");
		return NULL;
	}
	printf("fopen success!\n");
	
	return fp;									
}


void fwrite_file(FILE * fp,char * save)
{
	int ret;
	ret = fwrite(save,1,strlen(save),fp);
	if(ret == -1)
	{
		printf("fwrite error\n");
		return ;
	}
	fflush(fp);//冲洗流,立刻把内存内容写入磁盘
	printf("fwrite success!\n");
}

int main()
{
	//打开文件
	FILE * fp = fopen_file();

	char str[128] = {'0'};//保存输入的字符串
	char save[128] = {'0'};;//保存字符串转化为十六进制的数据

	Node * list = NULL;//初始化空链表
	
	//输入任意字符串
	while(scanf("%s",str) != EOF)	//循环输入
	{
		if(strcmp(str,"#") == 0)
		{
			printf("Iput Over!\n");
			break;
		}

		list = Add_Node(list, str);

		str_to_hex(str, strlen(str), save, strlen(str));
		printf("%s\n",save);

		//写入文件
		fwrite_file(fp, save);
	}

	print_list(list);

	int len = Elem_num(list);
	//printf("len = %d\n",len);

	//printf("%c\n",*Find_data_addr(list, 2));

	list = quick_sort(list, 0, len - 1);//快速排序

	printf("After Quick Sort:\n");
	print_list(list);

	Destroy_list(list);

	return 0;
}

最后:

        我把代码写在一个.c了,有精力可以分模块写,.c .h分开写,再搞个Makefile啥的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值