C/C++字符串数组的比较及其赋值所踩过的坑

这个是在在跟着B站上学习时自己出现的困惑,推荐B站一个UP,我个人感觉讲的非常好。懒猫老师
进入正题
自己在编写一段链表的学生管理系统时出现了需要按照学号进行各种操作的问题
首先会用到结构体这是肯定的
然后就出现了我自己直接用两个字符串数组进行比大小的行为
我单步运行找到了问题但是不知道怎么改,这就很尴尬了
随后B站问老师,加上CSDN搜索终于找到了怎么修改。
举个例子:
例1:
对应的是strcmp函数,需要头文件<stdio.h>和<string.h>,
int i=strcmp(s1,s2);
即比较s1和s2两个字符串数组的大小
s1 < s2 则 i < 0
s1 = s2 则 i = 0
s1 > s2 则 i > 0

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

int main()
{
	char s1[20];
	char s2[20];
	int i;
	printf("请输入s1:\n");
	scanf("%s",&s1);
	printf("请输入s2:\n");
	scanf("%s",&s2);
	i=strcmp(s1,s2);
	//在这块就是将两个字符串数组进行比较
	//切记不可以直接比(来自一个被坑死的傻子)
	if(i<0)
	{
		printf("s1<s2\n");
	}
	else if(i==0)
	{
		printf("s1=s2\n");
	}
	else
		printf("s1>s2");
	return 0;
}

例2:
对应的是strcpy函数,需要头文件<stdio.h>和<string.h>,
strcpy(s1,s2);
即将s2对应的字符串复制到s1也就相当于给s1赋值。

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

int main()
{
	char s1[20];
	char s2[20]={"hello!"};
	printf("请输入s1:\n");
	scanf("%s",&s1);
	printf("s1=%s\ns2=%s\n",s1,s2);
	strcpy(s1,s2);	//将s2复制到s1,对s2没有影响,也就相当于给s1赋值 
	printf("复制后:\n");
	printf("s1=%s\ns2=%s\n",s1,s2);
	
	
}

这个管理系统还可以进一步完善,代码如下:

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

//定义学生数据的结构体
typedef struct Student{
	char stu_No[20];
	char stu_Name[11];
}st;

//Student是我们定义的结构体类型
//st是我们定义的Student类型的一个变量
//中间定义的两个是对应结构体的内部元素


//定义每条记录的节点数据结构
typedef struct node{
	struct Student data;//数据域
	struct node *next;	//指针域
}Node,*Link;
//Node为node类型的别名,Link为node类型的指针别名


void myMenu() {
	printf("----------------------Menu---------------------\n");
	printf("	1 增加学生记录		 2 删除学生记录		\n");
	printf("	3 查找学生记录		 4 修改学生记录		\n");
	printf("	5 统计学生人数		 6 显示学生记录		\n");
	printf("	7 退出系统								\n");
	printf("-----------------------------------------------\n");
}

//输入需要操作的学生学号
//void inputStudentNo(char s[],char no[]){
//	printf("请输入要%s的学生学号:",s);
//	scanf_s("%s",&no);
//}

//学生节点的输入函数
void inputStudent(Link student){
	printf("请输入学生学号:\n");
	scanf("%s",&student->data.stu_No);
	printf("请输入学生姓名:\n");
	scanf("%s",&student->data.stu_Name);
	
	//每个新创建的节点都需要将其next域初始化为NIULL
	student->next = NULL;
}


//按序输入且排序
bool addNode(Link head){
	Link p, q;//p,q两个节点一前一后
	Link node;//node指针指向新创建的节点
	node = (Link)malloc(sizeof(Node));//创建一个新的节点
	node->next=NULL; 
	inputStudent(node);

	q = head;
	p = head->next;//p指向第一个有效节点
	if (head->next == NULL)//是否为全空链表
	{
		head->next = node;
	}
	else
	{
		while (p != NULL)
		{
			int i;
			i=(strcmp (node->data.stu_No ,p->data.stu_No));//比较两个字符串数组的大小,头文件加<string.h> 
			if (i<0)
			{
				q->next = node;//相当于再p和q之间插入了数据
				node->next = p;
				return true;
			}
			else
			{
				q = p;
				p = p->next;//数据大于p所对应的数字,则往后移继续比较
			}
		}
		q->next = node;
	}
	return true;
}

//给出学号,删除某节点
bool del(Link head){
	printf("请输入所需删除的学生学号:\n");
	char stu_del[20];
	scanf("%s",&stu_del);
	Link p, q;
	q = head;
	p = head->next;
	while (p != NULL)
	{
		int i;
		i=(strcmp (stu_del ,p->data.stu_No));
		if (i==0)
		{
			q->next = p->next;
			free(p);
			return true;//找到,删除
		}
		else
		{
			q = p;
			p = p->next;//学号大于当前位置,后移不返回值
		}
	}
	return false;//已退出循环且未找到,返回false;
}


//学生信息展示
void display(Link head)
{
	Link p;
	p = head->next;
	printf("学号		姓名\n");
	while (p != NULL)
	{
		printf("%s		%s\n", p->data.stu_Name, p->data.stu_No);
		p = p->next;
	}
}


//链表的查询
bool search(Link head)
{
	char stu_search[20];
	printf("请输入所需查询的学生学号:");
	scanf("%s",&stu_search);
	Link p;
	p = head->next;
	while (p != NULL)
	{
		int i;
		i=(strcmp (stu_search ,p->data.stu_No));
		if (i==0)
		{
			printf("学生姓名:%s\n",p->data.stu_Name);
			return true;
		}
		else
		{
			p = p->next;
		}
	}
	return false;
}

//链表的修改
bool modify(Link head)
{
	char stu_modify[20];
	scanf("%s",&stu_modify);
	Link p, q;
	q = head;
	p = head->next;
	while (p != NULL)
	{
		int i;
		i=(strcmp (stu_modify,p->data.stu_No));
		if (i==0)
		{
			printf("请输入更改后姓名:");
			char name[11];
			scanf("%s", &name);
//			p->data.stu_Name = name;
			// 字符串数组只能在初始化时使用等号									
			//若后续要修改需要用如下所示复制函数
			//且加头文件<string.h>
			strcpy((p->data.stu_Name), name);
			return true;
		}
		else
		{
			q = p;
			p = p->next;
		}

	}
	return false;

}

//统计人数,即有效节点数
void count(Link head)
{
	Link p;
	int sum = 0;
	p = head->next;
	while (p != NULL)
	{
		sum++;
		p = p->next;
	}
	printf("总人数为:%d\n", sum);
}


//链表的清除,不能产生垃圾内存
void clearLink(Link head) {
	Link p, q;
	q = head;
	p = head->next;
	while (p != NULL)
	{
		q = p;
		p = p->next;
		free(q);
	}
	free(q);
}


int main(){
	Link head;
	int select;

	//建立表头
	head = (Link)malloc(sizeof(Node));
	head->next = NULL;

	while(1)
	{
		myMenu();
		printf("请输入你的选择(1-7):");
		scanf("%d",&select);
		switch (select)
		{
		case 1:
			//增加学生记录
			if (addNode(head))
				printf("成功插入一个学生记录。\n\n");
			break;
		case 2:
			//删除学生记录
			if (del(head))
				printf("\n已删除。\n");
			else 
				printf("\n删除失败。\n");
			break;
		case 3:
			//查询学生记录
			if (search(head))
				printf("已查询\n");
			else
				printf("未查询到\n");
			break;
		case 4:
			//修改学生记录
			if (modify(head))
				printf("修改成功\n");
			else
				printf("修改失败\n");
			break;
		case 5:
			//统计学生人数
			count(head);
			break;
		case 6:
			//显示学生记录
			display(head);
			break;
		case 7:
			//退出,并清除所有节点
			clearLink(head);
			printf("已释放链表。");
		default:
			printf("输入不正确请重新输入:\n");
			break; 
		}
	}
	return 0;
}

字符串数组比较引用
字符串数组比较引用
字符串数组赋值引用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值