用单链表优雅的写一个学生管理系统

2023-11-10

用单链表优雅的写一个学生管理系统

基本的数据结构:单链表(Singly Linked List)中我们了解了如何用动态内存申请创建单链表,如何对单链表进行一些简单的操作。为进一步了解单链表以及其结构具有的功能,那么现在我们就用单链表来搞点事情。(用单链表来做一个“增”,“删”,“改”,“查”系统)

菜单设计

学生信息管理系统,酒店管理系统,火车票管理系统等等无非涉及“增”,“删”,“改”,“查”这四个功能。所以我们了解这种系统运作的本质后都可以类比来写。

首先我们将系统的菜单设计出来。有了菜单我们在写程序时就有一个大纲,这是因为系统的菜单上显示了系统的功能 ,对应于不同的功能我们需要不同的模块去实现。我们用代码一个个去实现菜单上的功能。当菜单上所有的功能全部实现完后我们的系统也就基本做好了。当然在系统中有些功能是隐藏的,例如在本案例中我们默认了保存到文件的功能。这里保存到文件的功能被隐藏了,我们也需要将其实现。

void systemMenu()//菜单
{

	//菜单--功能
	//隐藏的功能:同步保存到文件

	printf("--------------【学生管理系统】--------------\n");
	printf("\t\t0.退出系统\n");

	//  主要的功能:  增 删 改 查
	printf("\t\t1.插入信息\n");//增
	printf("\t\t2.删除信息\n");//删
	printf("\t\t3.修改信息\n");//改
	printf("\t\t4.查找信息\n");//查

	printf("\t\t5.浏览信息\n");
	printf("---------------------------------------------\n");
	printf("请输入 (0-5):\n");
	//交互,提醒用户输入
}

按键交互

在设计完菜单后,对于菜单上的功能。我们如何进行选择去实现哪个功能呢?我们用户输入菜单中功能选项前的代码后,系统去实现其功能。这时候就用到我们的按键交互了。
这里的按键交互仅能够打印提示当前功能,具体的功能还需要我们后续用链表去实现

void keyDown()//按键交互
{
	int userKey;
	scanf("%d", &userKey);
	switch (userKey) 
	{
	case 0:
		printf("\t\t【退出系统】\n");
		
		break;
	case 1:
		printf("\t\t【插入信息】\n");
		
		break;
	case 2:
		printf("\t\t【删除信息】\n");
		
		break;
	case 3:
		printf("\t\t【修改信息】\n");
		
		break;
	case 4:
		printf("\t\t【查找信息】\n");
		
		break;
	case 5:
		printf("\t\t【浏览信息】\n");
		
		break;
	default:
		printf("输入错误,请重新输入.\n");
		
		break;
	}
}

入口函数

在完成上面两个步骤后我们来写一个入口函数进行测试一下,在最前面加上头文件:stdio.h 以及stdlib.h

int main(void)
{
	while (1)
	{
		systemMenu();
		keyDown(); 
		system("pause");
		system("cls");
	}
	return 0;
}

测试结果:
运行后结果显示菜单内容
在这里插入图片描述
交互按1回车后结果
在这里插入图片描述
从运行结果来看我们学生系统的菜单设计以及按键交互设计的符合预想。

设计数据

做学生信息管理系统即要求系统对学生的信息进行操作。那么我们需要确定管理学生的什么信息,以及用什么类型进行存储。比如录入学生姓名,学号,年龄,电话号码,家庭住址。
我们不难想到在这里需要建立一个结构体保存以上的所有项

struct student
{
	char name[20];
	char num[10];//学号
	int age;
	char tel[12];//电话号码
	char addr[20];//家庭住址
};

设计储存数据的结构——链表

在前面我们了解到链表就是结构体变量与结构体变量的连接,并且知道如何通过动态内存申请创建链表,并插入结点,删除结点,打印遍历链表(这里的插入结点和删除结点对应于学生管理系统中的“增”,“删”,打印遍历列表对应于学生管理系统中的浏览信息)。下面我们在以往链表的基础进行优化使其能够满足学生管理系统所需的功能。

  1. 我们将链表的创建与操作独立出来,新建.h文件,命名为singleLish.h。在菜单,按键交互以及入口函数所在的studentSystem.cpp文件中包含该singleLish.h文件。并将stdio.h 以及stdlib.h头文件移到singleLish.h中。
  2. 将结构体类型struct student 放在singleLish.h中,并在以往链表的基础上进行修改。这里我们注意要进行修改什么内容?我们来找不同点:之前结点的数据域类型是整形int,而在学生管理系统中结点的数据域类型为结构体类型struct student(刚接触结构体时我们可能会感觉有点不知所云。其实大可不必,我们要清楚一点:struct student是一种数据类型正如int为整形类型一样。同理struct student* 可以和int *进行类比)。在明白其区别仅仅是结点的数据域类型不同后我们就好办了。我们只需将数据域的类型由原来的int改为struct student就行了。当然在指定位置删除时,由于参与对比的数据类型的缘故,在删除结点时要用到strcmp(),添加头文件string.h。
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct student
{
	char name[20];
	char num[10];//学号
	int age;
	char tel[12];//电话号码
	char addr[20];//家庭住址
};
struct Node
{
	struct student data;
	struct Node* next;
};

/*创建列表(表头)*/
struct Node* createList()
{
	struct Node* headNode = (struct Node*)malloc(sizeof(struct Node));
	headNode->next = NULL;
	return headNode;
}
/*创建结点*/
struct Node* createNode(struct student data)
{
	struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
	newNode->data = data;
	newNode->next = NULL;
	return newNode;
}

/*插入结点*/
//头插法  录入信息
void insertNodeByHead(struct Node* headNode, struct student data)
{
	struct Node* newNode = createNode(data);
	newNode->next = headNode->next;
	headNode->next = newNode;
}

/*删除结点*/
void deleteNodeByAppoinNum(struct Node* headNode, char* num)
{
	struct Node* posNode = headNode->next;
	struct Node* posFrontNode = headNode;
	if (posNode == NULL)
	{
		printf("无相关内容,无法删除.\n");
		return;
	}
	else
	{  
		while (strcmp(posNode->data.num,num))
		{
			posFrontNode = posNode;
			posNode = posNode->next;
			if (posNode == NULL)
			{
				printf("未找到指定内容,无法删除.\n");
				return;
			}
		}
		posFrontNode->next = posNode->next;//删除结点posNode
		free(posNode);
		printf("已删除.\n");
	}
}

/*打印遍历*/
void printList(struct Node* headList)
{
	struct Node* pMode = headList->next;
	if (pMode == NULL)
		printf("没有录入数据,无法浏览.\n");
	else
	{
		printf("姓名\t学号\t\t年龄\t电话\t\t住址\n");
		while (pMode)
		{
			printf("%s\t%s\t%d\t%s\t%s\n", pMode->data.name, pMode->data.num, pMode->data.age,
				pMode->data.tel, pMode->data.addr);
			pMode = pMode->next;
		}
		printf("\n");
	}
}

我们仔细比对上面代码和之前的链表代码,不难发现其框架相同,仅有的不同就是由数据域类型的不同引起的差别。
这就不难解释为什么说所有的“增”,“删”,“改”,“查”系统都可以参照这样的链表格式来写了。

3.在上一步骤中我们通过可以实现链表的“增”和“删”,下面我们来进行“改”和“查”。首先我们来看“查”:
我们可以以学号(学号不会有相同的情况)为依据进行查找。创建一个“可移动的指针”pMode,首先让其指向链表的第一个存有数据的结点。然后使其与指定的学号用strcmp()进行比对。比对结果相同则返回这个节点的地址。仅返回地址我们还不能浏览所查找学号的信息,故我们需要进一步将返回的结点进行打印。如下:

/*指定位置查找*/
struct Node* searchNodeByAppoinNum(struct Node* headList, char* num)
{
	struct Node* pMode = headList->next;
	if (pMode == NULL)
		return pMode;
	else
	{
		while (strcmp(pMode->data.num, num))
		{
			pMode = pMode->next;
			if (pMode == NULL)
				break;
		}
		return pMode;
	}
}

/*打印结点的数据*/
void printNode(struct Node* curNode)
{
	printf("姓名\t学号\t\t年龄\t电话\t\t住址\n");
	printf("%s\t%s\t%d\t%s\t%s\n", curNode->data.name, curNode->data.num, curNode->data.age,
		curNode->data.tel, curNode->data.addr);
}

4.接着我们来尝试修改学生的信息。同查找结点一样我们先根据学号找到要修改的结点。此时的查找过程我们调用searchNodeByAppoinNum()即可,查找到后将查找到的结点返回给curNode即可,我们通过对curNode的数据域的修改来进行修改学生的信息。

void changeNodeByAppoinNum(struct Node* headList, char* num)
{
	if (searchNodeByAppoinNum(headList, num) == NULL)
		printf("未找到相关信息,无法修改.\n");
	else
	{
		printf("请输入新的学生信息.\n");
		struct Node* curNode = searchNodeByAppoinNum(headList, num);
		scanf("%s%s%d%s%s", curNode->data.name, curNode->data.num, &curNode->data.age,
			curNode->data.tel, curNode->data.addr);
	}
}

进一步完善按键交互

前面提到最初的按键交互仅仅能打印提示当前功能,具体的功能还需要我们后续用链表去实现。那么在链表内容完善后,我们来进一步优化按键交互,使按键交互具有其实际的功能。

这里我们在studentSystem.cpp中创建了一个全局struct Node*类型指针变量list,并初始化为NULL,接着在main()中调用list = createList(),创建链表表头。
在keyDown()中定义了一个临时结构体变量tempData

void keyDown()//按键交互
{
	int userKey;
	struct student tempData;
	scanf("%d", &userKey);
	switch (userKey) 
	{
	case 0:
		printf("\t\t【退出系统】\n");
		system("pause");
		exit(0);
		break;
	case 1:
		printf("\t\t【插入信息】\n");
		printf("请输入学生姓名,学号,年龄,电话,住址:");
		scanf("%s%s%d%s%s", tempData.name, tempData.num, &tempData.age,
			tempData.tel, tempData.addr);
		insertNodeByHead(list, tempData);
		break;
	case 2:
		printf("\t\t【删除信息】\n");
		printf("请输入你要删除的学生学号\n");
		scanf("%s", tempData.num);
		deleteNodeByAppoinNum(list, tempData.num);
		break;
	case 3:
		printf("\t\t【修改信息】\n");
		printf("请输入要修改的学生学号.\n");
		scanf("%s", tempData.num);
		changeNodeByAppoinNum(list, tempData.num);
		break;
	case 4:
		printf("\t\t【查找信息】\n");
		printf("请输入需要查找的学号:");
		scanf("%s", tempData.num);
		if (searchNodeByAppoinNum(list, tempData.num) == NULL)
			printf("未找到相关信息!\n");
		else
			printNode(searchNodeByAppoinNum(list, tempData.num));
		break;
	case 5:
		printf("\t\t【浏览信息】\n");
		printList(list);
		break;
	default:
		printf("输入错误,请重新输入.\n");
		break;
	}
}

文件操作——将数据同步到文件

前面的工作可以说已经完成了一个学生管理系统。
下面我们为其新添加一个功能——同步到文件的功能,以便我们推出系统后,数据能同步保存下来

/*写在singleLish.h*/
/*文件操作*/
void readInfoFromFile(const char* fileName, struct Node* headList)
{
	FILE* fp = fopen(fileName, "r");
	if (fp == NULL)	
	{
		fp = fopen(fileName, "w");
	}
	struct student tempData;
	while (fscanf(fp,"%s\t%s\t%d\t%s\t%s\n", tempData.name, tempData.num, &tempData.age,
		tempData.tel, tempData.addr) != EOF)
	{
		insertNodeByHead(headList, tempData);
		memset(&tempData, 0, sizeof(tempData)); 
	}
	fclose(fp);
}
void saveInfoToFile(const char* fileName, struct Node* headList)
{
	FILE* fp = fopen(fileName, "w");
	struct Node* pMode = headList->next;
	while (pMode)
	{
		fprintf(fp,"%s\t%s\t%d\t%s\t%s\n", pMode->data.name, pMode->data.num, pMode->data.age,
			pMode->data.tel, pMode->data.addr);
		pMode = pMode->next;
	}
	fclose(fp);
}

另外需要在用户交互过程中,在插入,删除,修改数据后进行调用saveInfoToFile()进行保存,在入口函数循环前面调用readInfoFromFile(),打开文件。以便读取文件中存储的数据。

大家可以自己测试下文件操作

附上源码:

//studentSystem.cpp
#define _CRT_SECURE_NO_WARNINGS
#include"singleList.h"
struct Node* list = NULL;
void systemMenu()//菜单
{

	//菜单--功能
	//隐藏的功能:同步保存到文件

	printf("--------------【学生管理系统】--------------\n");
	printf("\t\t0.退出系统\n");

	//  主要的功能:  增 删 改 查
	printf("\t\t1.插入信息\n");//增
	printf("\t\t2.删除信息\n");//删
	printf("\t\t3.修改信息\n");//改
	printf("\t\t4.查找信息\n");//查

	printf("\t\t5.浏览信息\n");
	printf("---------------------------------------------\n");
	printf("请输入 (0-5):\n");
	//交互,提醒用户输入
}
void keyDown()//按键交互
{
	int userKey;
	struct student tempData;
	scanf("%d", &userKey);
	switch (userKey) 
	{
	case 0:
		printf("\t\t【退出系统】\n");
		system("pause");
		exit(0);
		break;
	case 1:
		printf("\t\t【插入信息】\n");
		printf("请输入学生姓名,学号,年龄,电话,住址:");
		scanf("%s%s%d%s%s", tempData.name, tempData.num, &tempData.age,
			tempData.tel, tempData.addr);
		insertNodeByHead(list, tempData);
		saveInfoToFile("student.txt", list);

		break;
	case 2:
		printf("\t\t【删除信息】\n");
		printf("请输入你要删除的学生学号\n");
		scanf("%s", tempData.num);
		deleteNodeByAppoinNum(list, tempData.num);
		saveInfoToFile("student.txt", list);
		break;
	case 3:
		printf("\t\t【修改信息】\n");
		printf("请输入要修改的学生学号.\n");
		scanf("%s", tempData.num);
		changeNodeByAppoinNum(list, tempData.num);
		saveInfoToFile("student.txt", list);
		break;
	case 4:
		printf("\t\t【查找信息】\n");
		printf("请输入需要查找的学号:");
		scanf("%s", tempData.num);
		if (searchNodeByAppoinNum(list, tempData.num) == NULL)
			printf("未找到相关信息!\n");
		else
			printNode(searchNodeByAppoinNum(list, tempData.num));
		break;
	case 5:
		printf("\t\t【浏览信息】\n");
		printList(list);
		break;
	default:
		printf("输入错误,请重新输入.\n");
		break;
	}
}
int main(void)
{
	list = createList();
	readInfoFromFile("student.txt", list);
	while (1)
	{
		systemMenu();
		keyDown(); 
		system("pause");
		system("cls");
	}
	return 0;
}
//singleLish.h

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

struct student
{
	char name[20];
	char num[10];//学号
	int age;
	char tel[12];//电话号码
	char addr[20];//家庭住址
};

struct Node
{
	struct student data;
	struct Node* next;
};

//链表就是结构体变量与结构体变量连接在一起
//指针变为变量的第二种方法:动态内存申请
/*创建列表(表头)*/
struct Node* createList()
{
	 //有表头链表:第一个结点不存储数据
	 //无表头链表:第一个结点存储数据
	struct Node* headNode = (struct Node*)malloc(sizeof(struct Node));
	headNode->next = NULL;
	return headNode;
}
/*创建结点*/
struct Node* createNode(struct student data)
{
	struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
	newNode->data = data;
	newNode->next = NULL;
	return newNode;
}


/*插入结点*/
//头插法  录入信息
void insertNodeByHead(struct Node* headNode, struct student data)
{
	struct Node* newNode = createNode(data);
	newNode->next = headNode->next;
	headNode->next = newNode;
}

/*删除结点*/
void deleteNodeByAppoinNum(struct Node* headNode, char* num)
{
	struct Node* posNode = headNode->next;
	struct Node* posFrontNode = headNode;
	if (posNode == NULL)
	{
		printf("无相关内容,无法删除.\n");
		return;
	}
	else
	{  
		while (strcmp(posNode->data.num,num))
		{
			posFrontNode = posNode;
			posNode = posNode->next;
			if (posNode == NULL)
			{
				printf("未找到指定内容,无法删除.\n");
				return;
			}
		}
		posFrontNode->next = posNode->next;//删除结点posNode
		free(posNode);
		printf("已删除.\n");
	}
}



/*打印遍历*/
void printList(struct Node* headList)
{
	struct Node* pMode = headList->next;
	if (pMode == NULL)
		printf("没有录入数据,无法浏览.\n");
	else
	{
		printf("姓名\t学号\t\t年龄\t电话\t\t住址\n");
		while (pMode)
		{
			printf("%s\t%s\t%d\t%s\t%s\n", pMode->data.name, pMode->data.num, pMode->data.age,
				pMode->data.tel, pMode->data.addr);
			pMode = pMode->next;
		}
		printf("\n");
	}
}



/*指定位置查找*/
struct Node* searchNodeByAppoinNum(struct Node* headList, char* num)
{
	struct Node* pMode = headList->next;
	if (pMode == NULL)
		return pMode;
	else
	{
		while (strcmp(pMode->data.num, num))
		{
			pMode = pMode->next;
			if (pMode == NULL)
				break;
		}
		return pMode;
	}
}

/*打印结点的数据*/
void printNode(struct Node* curNode)
{
	printf("姓名\t学号\t\t年龄\t电话\t\t住址\n");
	printf("%s\t%s\t%d\t%s\t%s\n", curNode->data.name, curNode->data.num, curNode->data.age,
		curNode->data.tel, curNode->data.addr);
}

void changeNodeByAppoinNum(struct Node* headList, char* num)
{
	if (searchNodeByAppoinNum(headList, num) == NULL)
		printf("未找到相关信息,无法修改.\n");
	else
	{
		printf("请输入新的学生信息.\n");
		struct Node* curNode = searchNodeByAppoinNum(headList, num);
		scanf("%s%s%d%s%s", curNode->data.name, curNode->data.num, &curNode->data.age,
			curNode->data.tel, curNode->data.addr);
	}
}



/*文件操作*/
void readInfoFromFile(const char* fileName, struct Node* headList)
{
	FILE* fp = fopen(fileName, "r");
	if (fp == NULL)	
	{
		fp = fopen(fileName, "w");
	}
	struct student tempData;
	while (fscanf(fp,"%s\t%s\t%d\t%s\t%s\n", tempData.name, tempData.num, &tempData.age,
		tempData.tel, tempData.addr) != EOF)
	{
		insertNodeByHead(headList, tempData);
		memset(&tempData, 0, sizeof(tempData)); 
	}
	fclose(fp);
}
void saveInfoToFile(const char* fileName, struct Node* headList)
{
	FILE* fp = fopen(fileName, "w");
	struct Node* pMode = headList->next;
	while (pMode)
	{
		fprintf(fp,"%s\t%s\t%d\t%s\t%s\n", pMode->data.name, pMode->data.num, pMode->data.age,
			pMode->data.tel, pMode->data.addr);
		pMode = pMode->next;
	}
	fclose(fp);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

用单链表优雅的写一个学生管理系统 的相关文章

  • 如何将 #ifdef DEBUG 添加到 Xcode?

    我的项目中有一些代码永远不应该在发布版本中使用 但在测试时很有用 我想做这样的事情 ifdef DEBUG Run my debugging only code endif 在 Xcode 4 中哪里添加 DEBUG 设置 我尝试将其放入
  • 在新的浏览器进程中打开 URL

    我需要在新的浏览器进程中打开 URL 当浏览器进程退出时我需要收到通知 我当前使用的代码如下 Process browser new Process browser EnableRaisingEvents true browser Star
  • 互斥体实现可以互换(独立于线程实现)

    所有互斥体实现最终都会调用相同的基本系统 硬件调用吗 这意味着它们可以互换吗 具体来说 如果我使用 gnu parallel算法 使用openmp 并且我想让他们称之为线程安全的类我可以使用boost mutex用于锁定 或者我必须编写自己
  • 在 Unity 进程和另一个 C# 进程之间进行本地 IPC 的最快方法 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我希望每秒大约 30 次从 C 应用程序向我的 Unity 应用程序传送大量数据 由于 Unity 不支持映射内存和管道 我考虑了 t
  • 单元测试一起运行时失败,单独运行时通过

    所以我的单元测试遇到了一些问题 我不能只是将它们复制并粘贴到这里 但我会尽力而为 问题似乎是 如果我一项一项地运行测试 一切都会按预期进行 但如果我告诉它一起运行测试 则 1 5 将通过 TestMethod public void Obj
  • 读取文件特定行号的有效方法。 (奖励:Python 手册印刷错误)

    我有一个 100 GB 的文本文件 它是来自数据库的 BCP 转储 当我尝试导入它时BULK INSERT 我在第 219506324 行上收到一个神秘错误 在解决此问题之前 我想看看这一行 但可惜的是我最喜欢的方法 import line
  • 存储来自其他程序的事件

    我想将其他应用程序的事件存储在我自己的应用程序中 事件示例 打开 最小化 Word 或打开文件时 这样的事可能吗 运行程序 http msdn microsoft com en us library ms813609 aspx and 打开
  • 在 C# 中循环遍历文件文件夹的最简单方法是什么?

    我尝试编写一个程序 使用包含相关文件路径的配置文件来导航本地文件系统 我的问题是 在 C 中执行文件 I O 这将是从桌面应用程序到服务器并返回 和文件系统导航时使用的最佳实践是什么 我知道如何谷歌 并且找到了几种解决方案 但我想知道各种功
  • 关于在 Windows 上使用 WiFi Direct Api?

    我目前正在开发一个应用程序 我需要在其中创建链接 阅读 无线网络连接 在桌面应用程序 在 Windows 10 上 和平板电脑 Android 但无关紧要 之间 工作流程 按钮 gt 如果需要提升权限 gt 创建类似托管网络的 WiFi 网
  • 使用 JNI 从 Java 代码中检索 String 值的内存泄漏

    我使用 GetStringUTFChars 从使用 JNI 的 java 代码中检索字符串的值 并使用 ReleaseStringUTFChars 释放该字符串 当代码在 JRE 1 4 上运行时 不会出现内存泄漏 但如果相同的代码在 JR
  • 上下文敏感与歧义

    我对上下文敏感性和歧义如何相互影响感到困惑 我认为正确的是 歧义 歧义语法会导致使用左推导或右推导构建多个解析树 所有可能的语法都是二义性的语言是二义性语言 例如 C 是一种不明确的语言 因为 x y 总是可以表示两个不同的事物 如下所述
  • 将 log4net 与 Autofac 结合使用

    我正在尝试将 log4net 与 Autofac 一起使用 我粘贴了这段代码http autofac readthedocs org en latest examples log4net html http autofac readthed
  • 私有模板函数

    我有一堂课 C h class C private template
  • 有人可以提供一个使用 Amazon Web Services 的 itemsearch 的 C# 示例吗

    我正在尝试使用 Amazon Web Services 查询艺术家和标题信息并接收回专辑封面 使用 C 我找不到任何与此接近的示例 所有在线示例都已过时 并且不适用于 AWS 的较新版本 有一个开源项目CodePlex http www c
  • gcc 的配置选项如何确定默认枚举大小(短或非短)?

    我尝试了一些 gcc 编译器来查看默认枚举大小是否很短 至少一个字节 强制使用 fshort enums 或无短 至少 4 个字节 强制使用 fno short enums user host echo Static assert 4 si
  • C++ 密码屏蔽

    我正在编写一个代码来接收密码输入 下面是我的代码 程序运行良好 但问题是除了数字和字母字符之外的其他键也被读取 例如删除 插入等 我知道如何避免它吗 特q string pw char c while c 13 Loop until Ent
  • Server.MapPath - 给定的物理路径,预期的虚拟路径

    我正在使用这行代码 var files Directory GetFiles Server MapPath E ftproot sales 在文件夹中查找文件 但是我收到错误消息说 给定物理路径但虚拟路径 预期的 我对在 C 中使用 Sys
  • 有没有办法强制显示工具提示?

    我有一个验证字段的方法 如果无法验证 该字段将被清除并标记为红色 我还希望在框上方弹出一个工具提示 并向用户显示该值无效的消息 有没有办法做到这一点 并且可以控制工具提示显示的时间 我怎样才能让它自己弹出而不是鼠标悬停时弹出 If the
  • 线程和 fork()。我该如何处理呢? [复制]

    这个问题在这里已经有答案了 可能的重复 多线程程序中的fork https stackoverflow com questions 1235516 fork in multi threaded program 如果我有一个使用 fork 的
  • memset 未填充数组

    u32 iterations 5 u32 ecx u32 malloc sizeof u32 iterations memset ecx 0xBAADF00D sizeof u32 iterations printf 8X n ecx 0

随机推荐

  • msvcp120.dll文件丢失如何解决?

    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题 如果是新手第一时间会认为是软件或游戏出错了 其实并不是这样 其主要原因就是你电脑系统的该dll文件丢失了或者损坏了 这时你只需下载这个msvcp120 dll文件进行安装 前提是找到
  • InvalidIndexError: (slice(None, None, None), None)

    在对照书复现代码时 1 直接将X Y画图不会报错 2 引入线性回归模型 再用拟合的数据画图就报错 原因 需要转换数据格式 import pandas as pd import matplotlib pyplot as plt import
  • 规避【虚拟专线技术】使用风险实现业务系统安全

    本文为作者学习文章 按作者习惯写成 如有错误或需要追加内容请留言 不喜勿喷 本文为追加文章 后期慢慢追加 一 技战法描述 VPN是利用Internet等公共网络基础设施 通过隧道加密通信技 术 为用户提供安全的数据通信的专用网络 可以实现不
  • 使用EasyPoi导入导出Excel

    easypoi功能如同名字easy 主打的功能就是容易 让一个没见接触过poi的人员 就可以方便的写出Excel导出 Excel模板导出 Excel导入 Word模板导出 通过简单的注解和模板 语言 熟悉的表达式语法 完成以前复杂的写法 这
  • idea Ctrl+Alt+T 快捷键失效、无法弹出surround with、与qq热键冲突-解决办法

    idea Ctrl Alt T 快捷键失效 无法弹出surround with 与qq热键冲突 解决办法 1 问题描述 2 解决方法1 3 解决方法2 1 问题描述 idea快捷键 CTRL ALT T 这个快捷键失效了 显然是热键冲突 其
  • Web中间件常见安全漏洞总结

    IIS IIS是Internet Information Services的缩写 意为互联网信息服务 是由微软公司提供的基于运行Microsoft Windows的互联网基本服务 IIS目前只适用于Windows系统 不适用于其他操作系统
  • Beyond Compare代码对比工具

    一个程序员的工作不仅仅是写代码 还有代码的检查 比较 版本日志等等 所以一个聪明的程序员会利用各种工具来简化这些工作 比如 代码的检查 我们会用一些ide 如写ios用xcode 写c 用vs 写android用android studio
  • PyQt5打开文件目录(QTreeView)并在QT界面输出文件目录并双击文件返回文件目录名

    最近发现了一个挺厉害的人工智能学习网站 内容通俗易懂 风趣幽默 感兴趣的可以点击此链接进行查看 床长人工智能教程 废话不多说 请看正文 打开整个文件目录 直接打开电脑的各个文件目录 显示出c盘 d盘等 如下图所示 代码如下 import s
  • win10与centos7的双系统U盘安装(一:制作u盘启动盘)

    博主近来在学习linux系统 当然学习第一步自然是安装系统了 博主选择的是centos7 博主自己的电脑是联想的 系统是win10专业版 在历经数次失败后 博主成功使用u盘安装了win10和centos的双系统 并且恢复了win10的启动项
  • 【模板】有理数取余(小白版)

    模板 有理数取余 洛谷P2613 题目链接 https www luogu com cn problem P2613 解题思路 不知道你是如何找到这个题解的 或者直接百度的 或者在我的其他题解里链接过来的 有理数取余这是一个知识点 也可能配
  • golang 两数之和,给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标

    给定一个整数数组 nums 和一个整数目标值 target 请你在该数组中找出 和为目标值 target 的那 两个 整数 并返回它们的数组下标 你可以假设每种输入只会对应一个答案 但是 数组中同一个元素在答案里不能重复出现 你可以按任意顺
  • 三目运算符的多层嵌套

    三目运算符的基础用法是二选一 当我们想多选一时就可以利用三目运算符的多层嵌套来完成 可以替代if多层判断 三目运算符的结构 根据不同的条件 执行不同的操作 返回不同的值 嵌套语法 条件1 值1或操作1 如果满足条件1 就返回值1或执行操作1
  • 超级账本Fabric区块链用弹珠游戏Marbles 部署

    Marbles 演示 Marbles GitHub地址 关于 Marbles 这个应用程序的基础网络是 Hyperledger Fabric 后者是一个 Linux Foundation 项目 您可能想查阅以下操作说明来稍微了解一下 Hyp
  • dumpsys meminfo内存分析解读(收集整合)

    OOM机制是机器底层的一种强制保鲜 在OOM发生的时候内核会排序强制杀掉进程来保证系统的继续运行 同样这种OOM异常容易发生在低内存机器上 比如512M 首先系统会根据程序是否是空进程 已经由用户关闭的不带有任何服务和provider的进程
  • bootstrap File Input 多文件上传插件使用记录(二)删除原文件

    bootstrap File Input 多文件上传插件使用记录 二 删除原文件 转自https blog csdn net github 36086968 article details 72830855 在上一篇文章中 主要介绍了fil
  • 【基础知识】4、python-opencv 超详细介绍

    文章目录 一 概述 1 1 安装 1 2 图像的表示 二 图像 2 1 读 存 显示 下载 2 1 1 读存显示 imread imwrite 2 1 2 下载 2 1 2 1 urllib 2 1 2 2 scikit image 2 2
  • 如何获取C++ Array的大小

    参考自chromium的处理方法如下 template
  • linux查看文件夹目录大小

    1 磁盘还剩多少空间 df h 2 当前的文件夹下的磁盘使用情况 du max depth 1 h 3 查看单个文件夹目录大小 du sh 文件或文件夹路径
  • 超级简单无任何第三方软件在安卓子系统中安装APK

    首先 你需要安装好安卓子系统 安装方法自行搜索 我是通过知乎网友的链接在微软商店直接下载的安卓子系统 无需先下载亚马逊商店 商店是后来自己装的 正事 打开子系统 高级设置 实验性功能 共享用户文件夹 开启 可以自定义文件夹 将需要的apk文
  • 用单链表优雅的写一个学生管理系统

    用单链表优雅的写一个学生管理系统 在基本的数据结构 单链表 Singly Linked List 中我们了解了如何用动态内存申请创建单链表 如何对单链表进行一些简单的操作 为进一步了解单链表以及其结构具有的功能 那么现在我们就用单链表来搞点