草庐IT

c语言实现通讯录管理系统

跑不死的程序员 2023-04-11 原文

目录

一、前言

二、通讯录的实现

1.关于通讯录的前期准备

(1)菜单的实现

(2)关于联系人结构体的创建

(3)实现菜单选项的功能

(4)关于全局变量的定义

 2、通讯录的功能实现

(1)初始化通讯录

(2)增加联系人

 (3)打印通讯录

(4)查找联系人

(5)修改联系人

(6)删除联系人 

三、关于通讯录的优化

1、通讯录结构体的改进

2、初始化结构体

3.增容

 4.释放内存

四、总结


一、前言

本文将会用c语言实现一个通讯录的系统,并且存储若干人的信息,每个人的信息包括:姓名,性别,年龄,电话号码,住址。此通讯录系统的功能包括: 1.增加联系人 2.删除对应的联系人 3.查找联系人 4.修改联系人的信息 5.排序此通讯录 6.打印出通讯录每个人的信息

二、通讯录的实现

1.关于通讯录的前期准备

(1)菜单的实现

首先关于一个通讯录,建立一个菜单是很重要的,菜单能够实现和用户的交互。

因此我们需要建立一个菜单,并且菜单立马应该包括通讯录立马该有的功能,以便于用户的操作

代码如下:

void menu()
{
	printf("=====================================\n");
	printf("============1.增加联系人=============\n");
	printf("============2.删除联系人=============\n");
	printf("============3.查找联系人=============\n");
	printf("============4.修改联系人=============\n");
	printf("============5.排序通讯录=============\n");
	printf("============6.打印通讯录=============\n");
	printf("============0.退出通讯录=============\n");
	printf("=====================================\n");
}

效果差不都就是这样子

(2)关于联系人结构体的创建

这里我们需要利用结构体来实现实现前言中的通讯录功能以及联系人信息,我将利用两个结构体来构建我们需要的东西。

typedef struct PeoInfo
{
	char name[NAME_MAX];
	char sex[SEX_MAX];
	int age;
	char tele[TELE_MAX];
	char addr[ADDR_MAX];
}Peo;
typedef struct Contact
{
	Peo con[PON_MAX];
	int sz;//记录数量
}contact;

关于第一个结构体Peo是关于个人信息的存储,第二个结构体构建了 我们需要的通讯录,con来作为以第一个结构体为类型的数组,sz来记录这个结构体存储个人信息的数量。

(3)实现菜单选项的功能

我们需要根据菜单里面的选项来选择进行我们需要实现的功能,比如我们想假如一个用户信息,我们就输入1就会进行用户假如的操作,我们想退出程序我们输入0就可以退出。我选择利用枚举变量的形式来实现,讲操作变成数字,利用switch选择语句来实现各自的功能。

enum Option//利用枚举变量来定义
{
	exit,//0
	add,//1
	del,//2
	search,//3
	modify,//4
	sort,//5
	print//6
};
void test()
{
	contact con;//建立结构体
	InitCon(&con);
	int input = 0;
	do {
		menu();
		scanf("%d", &input);
		switch (input)
		{
		case add:
			AddCon(&con);
			break;
		case del:
			DelCon(&con);
			break;
		case search:
		SearchCon(&con);
			break;
		case modify:
			ModifyCon(&con);
			break;
		case sort:
			SortCon(&con);
			break;
		case print:
			PrintCon(&con);
			break;
		case exit:
			printf("退出程序,欢迎使用!\n");
			break;
		default:
			printf("没有找到此数字匹配的操作!!\n");
		}
	} while (input);
}

(4)关于全局变量的定义

为了实现这些变量,并且方便后期的处理数组大小,所以我们可以利用宏来实现这个功能

#define NAME_MAX 20//姓名的长度
#define SEX_MAX 5//性别的长度
#define TELE_MAX 12//电话号码的长度
#define ADDR_MAX 30//地址长度
#define PON_MAX 1000//通讯录的大小

 2、通讯录的功能实现

(1)初始化通讯录

刚刚开始我们创建了通讯录的结构体,但是我们不难发现,因为没有定义的原因,他们里面存的都是随机数,因此我们需要对他们进行初始化防止后面的失误。初始化很简单就是把我们通讯录结构体里面的用户信息的结构体类型的数组进行初始化,这里我们可以浅浅用一个memset函数来实现,当然别忘了引用string的头文件,然后sz的初始化很简单就是初始化为0。

void InitCon(contact* pc)
{
	assert(pc);
	pc->sz = 0;
	memset(pc->con, 0, sizeof(pc->con));
}//初始化结构体

(2)增加联系人

首先第一步我们完成第一步就可以创建关于加入联系人的函数,这个很简单我们只需要访问通讯录结构体里面的数组中的每个元素然后输入对应值就可以了

void AddCon(contact* pc)
{
	assert(pc);
	if (pc->sz == PON_MAX)
	{
		printf("通讯录满了!!\n");
	}
	printf("请输入姓名:>\n");
	scanf("%s", pc->con[pc->sz].name);
	printf("请输入性别:>\n");
	scanf("%s", pc->con[pc->sz].sex);
	printf("请输入年龄:>\n");
	scanf("%d", &(pc->con[pc->sz].age));//注意年龄在这里是一个int类型
	printf("请输入电话号码:>\n");
	scanf("%s", pc->con[pc->sz].tele);
	printf("请输入地址:>\n");
	scanf("%s", pc->con[pc->sz].addr);
	pc->sz++;
	printf("此用户添加成功!\n");
}

 

 (3)打印通讯录

打印通讯录也很简单,利用一个for循环根据sz的大小遍历结构体中的数组每个元素并且打印即可

void PrintCon(const contact* pc)
{
	assert(pc);
	printf("%-15s %-5s %-5s %-12s %-30s\n","姓名","性别","年龄","电话","地址");
	for (int i = 0; i < pc->sz; i++)
	{
		printf("%-15s %-5s %-5d %-12s %-30s\n", pc->con[i].name, pc->con[i].sex, pc->con[i].age, pc->con[i].tele, pc->con[i].addr);
	}
}

(4)查找联系人

查找联系人这边我们需要构建一个函数,这个函数需要去根据我们想要寻找的姓名去在通讯录中寻找这个人所对应的位置,加入找到了就可以返回对应位置的下标,否则返回-1。找到之后就和打印通讯录的操作差不多打印出来就好了。

int FindByName(const contact* pc, char* name)
{
	assert(pc && name);
	for (int i = 0; i < pc->sz; i++)
	{
		if (0 == strcmp(pc->con[i].name, name))
			return i;
    }
	return -1;
}//寻找或者删除联系人的下标
void SearchCon(const contact* pc)
{
	assert(pc);
	char name[NAME_MAX];
	printf("请输入需要寻找用户的名字:>\n");
	scanf("%s", name);
	int pos = FindByName(pc, name);//pos为要寻找的人的下标
	if (pos == -1)
	{
		printf("查无此人\n");
	}
	else
	{
		printf("%-15s %-5s %-5s %-12s %-30s\n", "姓名", "性别", "年龄", "电话", "地址");
		printf("%-15s %-5s %-5d %-12s %-30s\n", pc->con[pos].name, pc->con[pos].sex, pc->con[pos].age, pc->con[pos].tele, pc->con[pos].addr);
	}
}

 

(5)修改联系人

关于修改联系人这个内容,大多数的代码都是直接替换所有的内容,这样也会让一些本来就不用修改的信息又被修改了一遍,很麻烦,所有我的设计是,先让用户查找到需要修改的这个人然后选择是修改什么信息,然后重新输入嘞一部分的信息,这个其实就和菜单选项实现很相似,我们需要利用枚举变量,并且利用do...while语句来让他一直循环直到输入0为止,利用switch来根据用户的选项来跳到需要的操作。 

enum Con
{
	ERRO,
    NAME,
	SEX,
	AGE,
	TELE,
	ADDR
};
void ModifyCon(contact* pc)
{
	assert(pc);
	char name[NAME_MAX];
	printf("请输入需要修改信息用户的名字:>\n");
	scanf("%s", name);
	int pos = FindByName(pc, name);//pos为要寻找的人的下标
	if (pos == -1)
	{
		printf("查无此人\n");
	}
	else
	{
		int num = 0;
		do {
			printf("请输入你想修改此用户的信息\n");
			printf(" 0.退出 1.姓名 2.性别 3.年龄 4.电话 5.地址:>\n");			
			scanf("%d", &num);
			switch (num)
			{
			case NAME:
				printf("请输入你想修改的姓名:>\n");
				scanf("%s", pc->con[pos].name);
				break;
			case SEX:
				printf("请输入你想修改的性别:>\n");
				scanf("%s", pc->con[pos].sex);
				break;
			case AGE:
				printf("请输入你想修改的年龄:>\n");
				scanf("%d", &(pc->con[pos].age));
				break;
			case TELE:
				printf("请输入你想修改的电话:>\n");
				scanf("%s", pc->con[pos].tele);
				break;
			case ADDR:
				printf("请输入你想修改的地址:>\n");
				scanf("%s", pc->con[pos].addr);
				break;
			case 0:
				printf("不修改退回界面\n");
				break;
			default:printf("无效操作数!\n");
			}
		} while (num);
	}
}

 

(6)删除联系人 

这个操作也不算复杂,我的思路是,首先我们先利用刚刚查找的嘞个查找下标的函数,查找到我们需要寻找删除联系人的坐标,然后对他进行删除,删除之后呢我们需要把后面的元素往前移动,这就要利用for循环,但是对于for循环的次数要多加注意,因为稍不小心就会导致数组越界。

void DelCon(contact* pc)
{
	assert(pc);
	char name[NAME_MAX];
	printf("请输入需要删除用户的名字:>\n");
	scanf("%s", name);
	int pos = FindByName(pc, name);//pos为要寻找的人的下标
	if (pos == -1)
	{
		printf("查无此人\n");
	}
	else
	{
		for (int i = pos; i < pc->sz - 1; i++)
		{
			pc->con[i] = pc->con[i + 1];
		}
		pc->sz--;
		printf("删除成功!\n");
	}
}

(7)排序通讯录

这一步我们需要按照人名首字母的大小对于通讯录进行排序,就比如summer和banni,banni会在summer,这个排序其实和冒泡排序差不多,我们需要注意的是我们在交换两个数的时候我们需要定义的的嘞个中间数为联系人结构体类型,以免出错

void SortCon(contact* pc)
{
	if (pc->sz == 0)
	{
		printf("通讯录中没有联系人\n");
	}
	else
	{
		for (int i = 0; i < pc->sz - 1; i++)
		{
			for (int j = 0; j < pc->sz - 1 - i; j++)
			{
				if ((strcmp(pc->con[j].name, pc->con[j + 1].name)) > 0)
				{
					Peo temp = pc->con[j];
					pc->con[j] = pc->con[j + 1];
					pc->con[j + 1] = temp;
				}
			}
		}
		printf("排序成功!\n");
	}
}

 

这样我们需要的一个通讯录就这样实现了!

三、关于通讯录的优化

这个通讯录我们不难发现他有一个致命的缺点,就是我们初始化的通讯录大小为1000,但是当我们存满还想存元素的时候,编译器就会给我们报错,我们就需要继续手动增加空间,所以为了避免这样我们可以利用动态内存分配来定义我们的通讯录结构体。

1、通讯录结构体的改进

这边我们可以把之前的结构体里面的数组变成一个指针数组,并且为了考虑这个通讯录来回删除增加的缘故,一个sz来记录数组元素个数是不行的,我们需要在设定一个值为数组最大的空间,当sz和他相等的时候我们就需要扩充这个数组。

typedef struct Contact
{
	Peo* con;
	int sz;//记录数量
	int max;//记录通讯录当前的最大容量
}contact;

2、初始化结构体

这个初始化结构体,我们需要sz初始化为0,并且为con这个指针开辟一块空间,并且赋予max一个初始值,这个初始值我们可以用宏来定义我们初始化通讯录的大小

#define CON_MAX 3//通讯录初始化大小
void InitCon(contact* pc)
{
	assert(pc);
	pc->sz = 0;
	pc->max = CON_MAX;
    pc->con = (Peo*)malloc(sizeof(Peo) * pc->max);
	if (pc->con == NULL)
	{
		perror("InitContact::malloc");
		return;
	}
	memset(pc->con, 0, pc->max * sizeof(Peo));
}

3.增容

当我们增加联系人是sz == max的时候,我们可以利用realloc函数来实现扩容,每一次扩容两个空间

void CheckCapacity(contact* pc)
{
	//增容的代码
	if (pc->sz == pc->max)
	{
		Peo* tmp = (Peo*)realloc(pc->sz, (pc->max + 2) * sizeof(Peo));
		if (tmp != NULL)
		{
			pc->sz = tmp;
		}
		else
		{
			perror("CheckCapacity::realloc");
			return;
		}
		pc->max += 2;
		printf("增容成功\n");
	}
}

 4.释放内存

这边我们可以构建一个函数在这个程序结束之后释放内存

void DestroyContact(contact* pc)
{
	free(pc->con);
	pc->con = NULL;
	pc->max = 0;
	pc->sz = 0;
	printf("销毁成功\n");
}

四、总结

这个通讯录主要考察的是对于结构体的访问,还有对于结构体的创建,在编码的时候得务必细心,最后放上完整的源代码供大家参考

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

//类型的声明

#define MAX 1000

#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 12
#define ADDR_MAX 30

//通讯录初始状态的容量大小
#define DEFAULT_SZ 3

enum Option
{
	EXIT,//0
	ADD,
	DEL,
	SEARCH,
	MODIFY,
	SORT,
	PRINT
};
enum Con
{
	ERRO,
	NAME,
	SEX,
	AGE,
	TELE,
	ADDR
};

typedef struct PeoInfo
{
	char name[NAME_MAX];
	char sex[SEX_MAX];
	int age;
	char tele[TELE_MAX];
	char addr[ADDR_MAX];
} PeoInfo;
typedef struct Contact
{
	PeoInfo* data;//可以存放1000个人的信息
	int sz;//记录通讯中已经保存的信息个数
	int capacity;//记录通讯录当前的最大容量
}Contact;
//函数的声明
//初始化通讯录
void InitContact(Contact* pc);
//销毁通讯录
void DestroyContact(Contact* pc);
//增加联系人的信息
void AddContact(Contact* pc);
//打印通讯录中的信息
void PrintContact(const Contact* pc);
//删除指定联系人
void DelContact(Contact* pc);
//查找指定联系人
void SearchContact(const Contact* pc);
//保存通讯录的信息到文件
void SaveContact(const Contact* pc);
//通讯录排序
void SortCon(Contact* pc);
void ModifyCon(Contact* pc);
#define _CRT_SECURE_NO_WARNINGS 1

//动态的版本
//void InitContact(Contact* pc)
//{
//	assert(pc);
//	pc->sz = 0;
//	pc->capacity = DEFAULT_SZ;
//	pc->data = (PeoInfo*)malloc(pc->capacity * sizeof(PeoInfo));
//
//	if (pc->data == NULL)
//	{
//		perror("InitContact::malloc");
//		return;
//	}
//	memset(pc->data, 0, pc->capacity * sizeof(PeoInfo));
//}
void CheckCapacity(Contact* pc)
{
	//增容的代码
	if (pc->sz == pc->capacity)
	{
		PeoInfo* tmp = (PeoInfo*)realloc(pc->data, (pc->capacity + 2) * sizeof(PeoInfo));
		if (tmp != NULL)
		{
			pc->data = tmp;
		}
		else
		{
			perror("CheckCapacity::realloc");
			return;
		}
		pc->capacity += 2;
		printf("增容成功\n");
	}
}
void LoadContact(Contact* pc)
{
	//打开文件
	FILE* pf = fopen("contact.dat", "rb");
	if (pf == NULL)
	{
		perror("LoadContact::fopen");
		return;
	}
	//读文件
	PeoInfo tmp = { 0 };
	while (fread(&tmp, sizeof(PeoInfo), 1, pf))
	{
		CheckCapacity(pc);
		pc->data[pc->sz] = tmp;
		pc->sz++;
	}

	//关闭文件
	fclose(pf);
	pf = NULL;
}
//初始化通讯录 - 文件版本
void InitContact(Contact* pc)
{
	assert(pc);
	pc->sz = 0;
	pc->capacity = DEFAULT_SZ;
	pc->data = (PeoInfo*)malloc(pc->capacity * sizeof(PeoInfo));

	if (pc->data == NULL)
	{
		perror("InitContact::malloc");
		return;
	}
	memset(pc->data, 0, pc->capacity * sizeof(PeoInfo));

	//加载文件信息到通讯录中
	LoadContact(pc);
}
void DestroyContact(Contact* pc)
{
	free(pc->data);
	pc->data = NULL;
	pc->capacity = 0;
	pc->sz = 0;
	printf("销毁成功\n");
}
void AddContact(Contact* pc)
{
	assert(pc);

	//静态版本
	//if (pc->sz == MAX)
	//{
	//	printf("通讯录已满,无法添加\n");
	//	return;
	//}

	//动态的版本
	CheckCapacity(pc);

	//录入信息
	printf("请输入名字:>");
	scanf("%s", pc->data[pc->sz].name);
	printf("请输入年龄:>");
	scanf("%d", &(pc->data[pc->sz].age));
	printf("请输入性别:>");
	scanf("%s", pc->data[pc->sz].sex);
	printf("请输入电话:>");
	scanf("%s", pc->data[pc->sz].tele);
	printf("请输入地址:>");
	scanf("%s", pc->data[pc->sz].addr);

	pc->sz++;
	printf("添加成功\n");
}
void PrintContact(const Contact* pc)
{
	assert(pc);

	int i = 0;
	printf("%-20s %-5s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");

	for (i = 0; i < pc->sz; i++)
	{
		printf("%-20s %-5d %-5s %-12s %-30s\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tele, pc->data[i].addr);
	}
}

//找到了返回下标
//找不到返回-1
int FindByName(const Contact* pc, char name[])
{
	assert(pc);
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		if (0 == strcmp(pc->data[i].name, name))
		{
			return i;
		}
	}

	return -1;
}

void DelContact(Contact* pc)
{
	assert(pc);

	if (pc->sz == 0)
	{
		printf("通讯录已空,无法删除\n");
		return;
	}
	//删除
	//1. 找到
	char name[NAME_MAX] = { 0 };
	printf("请输入要删除人的名字:>");
	scanf("%s", name);
	int pos = FindByName(pc, name);
	if (pos == -1)
	{
		printf("要删除的人不存在\n");
		return;
	}
	//2. 删除
	int j = 0;
	for (j = pos; j < pc->sz - 1; j++)
	{
		pc->data[j] = pc->data[j + 1];
	}

	pc->sz--;
	printf("删除成功\n");
}

void SearchContact(const Contact* pc)
{
	char name[NAME_MAX] = { 0 };
	printf("请输入要查找人的名字:>");
	scanf("%s", name);
	int pos = FindByName(pc, name);
	if (pos == -1)
	{
		printf("要查找的人不存在\n");
		return;
	}
	printf("%-20s %-5s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");
	printf("%-20s %-5d %-5s %-12s %-30s\n", pc->data[pos].name, pc->data[pos].age, pc->data[pos].sex,
		pc->data[pos].tele, pc->data[pos].addr);
}


void SaveContact(const Contact* pc)
{
	FILE* pf = fopen("contact.dat", "wb");
	//回来本地建立一个contact.dat的记事本
	if (pf == NULL)
	{
		perror("SaveContact::fopen");
		return;
	}
	//写文件
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		fwrite(pc->data + i, sizeof(PeoInfo), 1, pf);
	}

	//关闭文件
	fclose(pf);
	pf = NULL;
}
void SortCon(Contact* pc)
{
	if (pc->sz == 0)
	{
		printf("通讯录中没有联系人\n");
	}
	else
	{
		for (int i = 0; i < pc->sz - 1; i++)
		{
			for (int j = 0; j < pc->sz - 1 - i; j++)
			{
				if ((strcmp(pc->data[j].name, pc->data[j + 1].name)) > 0)
				{
					PeoInfo temp = pc->data[j];
					pc->data[j] = pc->data[j + 1];
					pc->data[j + 1] = temp;
				}
			}
		}
		printf("排序成功!\n");
	}
}

void ModifyCon(Contact* pc)
{
	assert(pc);
	char name[NAME_MAX];
	printf("请输入需要修改信息用户的名字:>\n");
	scanf("%s", name);
	int pos = FindByName(pc, name);//pos为要寻找的人的下标
	if (pos == -1)
	{
		printf("查无此人\n");
	}
	else
	{
		int num = 0;
		do {
			printf("请输入你想修改此用户的信息\n");
			printf(" 0.退出 1.姓名 2.性别 3.年龄 4.电话 5.地址:>\n");
			scanf("%d", &num);
			switch (num)
			{
			case NAME:
				printf("请输入你想修改的姓名:>\n");
				scanf("%s", pc->data[pos].name);
				break;
			case SEX:
				printf("请输入你想修改的性别:>\n");
				scanf("%s", pc->data[pos].sex);
				break;
			case AGE:
				printf("请输入你想修改的年龄:>\n");
				scanf("%d", &(pc->data[pos].age));
				break;
			case TELE:
				printf("请输入你想修改的电话:>\n");
				scanf("%s", pc->data[pos].tele);
				break;
			case ADDR:
				printf("请输入你想修改的地址:>\n");
				scanf("%s", pc->data[pos].addr);
				break;
			case 0:
				printf("不修改退回界面\n");
				break;
			default:printf("无效操作数!\n");
			}
		} while (num);
	}
}

void menu()
{
	printf("*****************************************\n");
	printf("**** 1.增加联系人    2.删除联系人    ****\n");
	printf("**** 3.查找联系人    4.修改联系人    ****\n");
	printf("**** 5.通讯录排序    6.打印通讯录    ****\n");
	printf("****            0.退出               ****\n");
	printf("******************************************\n");
}

void test()
{
	int input = 0;
	Contact con;
	InitContact(&con);

	do
	{
		menu();
		printf("请输入你的选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case ADD:
			AddContact(&con);
			break;
		case DEL:
			DelContact(&con);
			break;
		case SEARCH:
			SearchContact(&con);
			break;
		case MODIFY:
			ModifyCon(&con);
			break;
		case SORT:
			SortCon(&con);
			break;
		case PRINT:
			PrintContact(&con);
			break;
		case EXIT:
			SaveContact(&con);
			DestroyContact(&con);
			printf("感谢使用\n");
			break;
		default:
			printf("非法输入\n");
			break;
		}
	} while (input);
}

int main()
{
	test();
	return 0;
}


感谢阅读!!!!

有关c语言实现通讯录管理系统的更多相关文章

  1. ruby - i18n Assets 管理/翻译 UI - 2

    我正在使用i18n从头开始​​构建一个多语言网络应用程序,虽然我自己可以处理一大堆yml文件,但我说的语言(非常)有限,最终我想寻求外部帮助帮助。我想知道这里是否有人在使用UI插件/gem(与django上的django-rosetta不同)来处理多个翻译器,其中一些翻译器不愿意或无法处理存储库中的100多个文件,处理语言数据。谢谢&问候,安德拉斯(如果您已经在ruby​​onrails-talk上遇到了这个问题,我们深表歉意) 最佳答案 有一个rails3branchofthetolkgem在github上。您可以通过在Gemfi

  2. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  3. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  4. ruby - 寻找通过阅读代码确定编程语言的ruby gem? - 2

    几个月前,我读了一篇关于ruby​​gem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:

  5. ruby-on-rails - 获取 inf-ruby 以使用 ruby​​ 版本管理器 (rvm) - 2

    我安装了ruby​​版本管理器,并将RVM安装的ruby​​实现设置为默认值,这样'哪个ruby'显示'~/.rvm/ruby-1.8.6-p383/bin/ruby'但是当我在emacs中打开inf-ruby缓冲区时,它使用安装在/usr/bin中的ruby​​。有没有办法让emacs像shell一样尊重ruby​​的路径?谢谢! 最佳答案 我创建了一个emacs扩展来将rvm集成到emacs中。如果您有兴趣,可以在这里获取:http://github.com/senny/rvm.el

  6. ruby-on-rails - 事件管理员日期过滤器日期格式自定义 - 2

    是否有简单的方法来更改默认ISO格式(yyyy-mm-dd)的ActiveAdmin日期过滤器显示格式? 最佳答案 您可以像这样为日期选择器提供额外的选项,而不是覆盖js:=f.input:my_date,as::datepicker,datepicker_options:{dateFormat:"mm/dd/yy"} 关于ruby-on-rails-事件管理员日期过滤器日期格式自定义,我们在StackOverflow上找到一个类似的问题: https://s

  7. 电脑0x0000001A蓝屏错误怎么U盘重装系统教学 - 2

      电脑0x0000001A蓝屏错误怎么U盘重装系统教学分享。有用户电脑开机之后遇到了系统蓝屏的情况。系统蓝屏问题很多时候都是系统bug,只有通过重装系统来进行解决。那么蓝屏问题如何通过U盘重装新系统来解决呢?来看看以下的详细操作方法教学吧。  准备工作:  1、U盘一个(尽量使用8G以上的U盘)。  2、一台正常联网可使用的电脑。  3、ghost或ISO系统镜像文件(Win10系统下载_Win10专业版_windows10正式版下载-系统之家)。  4、在本页面下载U盘启动盘制作工具:系统之家U盘启动工具。  U盘启动盘制作步骤:  注意:制作期间,U盘会被格式化,因此U盘中的重要文件请注

  8. 华为OD机试用Python实现 -【明明的随机数】 2023Q1A - 2

    华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o

  9. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  10. Unity 热更新技术 | (三) Lua语言基本介绍及下载安装 - 2

    ?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------

随机推荐