C语言顺序表图书管理系统实现:核心算法与完整代码

陈默
陈默
发布时间:2026-10-16| 6人浏览过
原创

基于C语言与顺序表(SqList)构建的图书管理系统,实现了包括插入、删除、查找、修改、排序以及TXT文件读写在内的全套数据管理功能。本教程通过解析核心代码逻辑,帮助读者理解线性表在实际应用中的内存管理与操作细节。

系统设计与数据结构准备

系统核心采用静态分配与动态扩容相结合的顺序表结构。首先需要定义图书元素 ElemType 和顺序表 SqList,其中图书信息包含ISBN、书名、主编、出版社及定价五个字段。

数据结构定义:

  • ElemType: 存储单条图书记录的单元结构。
  • SqList: 包含指向元素数组的指针 elem、当前长度 length 和当前容量 listsize 的结构体。

在初始化阶段,系统调用 InitList_Sq 函数,使用 malloc 分配初始内存(默认50个元素)。若内存分配失败则返回溢出错误,否则将长度置为0,并记录初始容量。

核心功能操作实现

系统通过菜单驱动调用底层函数,所有操作均围绕ISBN这一唯一标识符展开。

第1步:数据录入与插入检查

执行插入操作时,首先调用 LocateElem_Sq 遍历现有表项。若找到相同ISBN,则判定重复并拒绝插入;若未找到,则检查表是否已满。若已满,使用 realloc 动态扩容(每次增加10个单位),随后将新书信息追加至表尾,并更新长度。

第2步:按ISBN删除图书

删除流程先定位目标ISBN。若定位成功,将对应位置的元素暂存后,利用循环从该位置起将所有后续元素向前移动一位以填补空缺,最后将表长减1。此操作保证了表结构的连续性。

第3步:查找与修改属性

查找功能直接返回匹配元素的位序。修改功能在确认元素存在后,允许用户重新输入该图书的所有属性(ISBN、书名、主编、出版商、定价),并通过索引直接覆盖原内存中的数据。注意:修改时新输入的ISBN也会替换原有ISBN字段。

第4步:数据持久化与导入

系统支持将内存数据保存至TXT文件及从TXT导入。保存时,使用 fprintf 配合制表符(Tab)格式化输出各字段。导入时使用 fscanf 读取文本,需注意处理可能的空格或格式错误,并将读取的数据依次赋值给数组元素。

排序与显示逻辑

排序功能默认按ISBN字符串字典序进行升序排列,采用简单选择排序算法。打印函数则遍历整个有效长度,以固定宽度格式输出所有字段,确保屏幕显示对齐整齐。

完整源代码

以下代码整合了上述所有功能模块,可直接在C编译器中运行测试。

#include <stdio.h>
#include <stdlib.h>
#include <string.h> 
//头文件 
  
#define OK 1
#define ERROR 0
#define OVERFLOW -1
#define LIST_INIT_SIZE 50
#define LISTINCREMENT 10
//宏定义,即定义常量 

typedef int status;
typedef struct {
	char ISBN[15];
	char bookname[30];
	char writername[10];
	char publisher[20];
	float price;
} ElemType;
typedef struct {
	ElemType *elem;
	int length;
	int listsize; 	
} SqList; 
	//定义结构体类型,即  typedef 类型  类型名 
	
status  InitList_Sq(SqList &L)   
{ //构造一个空的线性表L。
	L.elem=(ElemType *)   malloc(LIST_INIT_SIZE*sizeof(ElemType));
	//申请初始化长度的内存 
	if(!L.elem){
	//如果L的序列非空 
		exit(OVERFLOW);   
		//说明L被重定义了,抛出溢出 
	}
	L.length=0;
	//默认L内有0个元素   
	L.listsize=LIST_INIT_SIZE; 
	//默认L的容量为初始化长度 
	return OK;
}

int LocateElem_Sq(SqList L,char ISBN[])
{    //在顺序表L中遍历查找第1个值与e.ISBN相等的元素的位序,若找到,返回其位序,否则返回0; 
	for(int i=0;i<L.length;i++){
		if(strcmp(ISBN,L.elem[i].ISBN)==0){
			return i+1;
		}
	}
	return 0;
}

status ListInsert_Sq(SqList &L,ElemType e)
{//元素e插入表尾
	ElemType *newbase;
	if(LocateElem_Sq(L,e.ISBN)){
		return ERROR;
	}
	if(L.length>=L.listsize) {
		newbase =(ElemType*)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType));
		if(!newbase){
			exit(OVERFLOW);
		}
		L.elem=newbase;
		L.listsize+=LISTINCREMENT;
	}
	L.elem[L.length]=e;
	L.length++;
	return OK;
}

status ListDelete_Sq(SqList &L,char ISBN[] ,ElemType &e)
{    //删除L中ISBN的元素,并返回删除元素; 
	int i,j;
	if((i=LocateElem_Sq(L,ISBN))==0){
		return ERROR;
	}
	
	e=L.elem[i-1];
	for(j=i;j<L.length;j++){
		L.elem[j-1]=L.elem[j];
	}
	L.length--;
	return OK;
}

status SetElem_Sq(SqList &L,int i,ElemType e)
{    //修改在i的位置的元素 
	if(i<1||i>L.length){
		return ERROR;
	}
	L.elem[i-1]=e;
	return OK;
}

void sort_ISBN(SqList &L)
{    //对表中所有元素进行排序; 
	int i,j,k;
	ElemType e;
	for(i=0;i<L.length-1;i++){
		k=i;
		for(j=i+1;j<L.length;j++){
			if(strcmp(L.elem[k].ISBN,L.elem[j].ISBN)>0){
				k=j;
			}
		}
		if(k!=i){
			e=L.elem[i];
			L.elem[i]=L.elem[k];
			L.elem[k]=e;
		}   
	}
}

void print(SqList L)
{    //打印出所有元素
	int i;
	printf("\n图书信息为:\n");
	for(i=0;i<L.length;i++){
		printf("%-15s%-30s%-10s%-20s%-6.2f\n",L.elem[i].ISBN,L.elem[i].bookname,L.elem[i].writername,L.elem[i].publisher,L.elem[i].price); 
	}   
}

void import(SqList &L,char *filename)
{    //从文件中导入信息 
	FILE *fp;
	int i;
	char ISBN[15],bookname[30],writername[10],publisher[20];
	float price;
	if((fp=fopen(filename,"r"))==NULL){
		printf("文件不存在!\n");
		return ;
	}
	i=0;
	while(!feof(fp)){
		fscanf(fp,"%s%s%s%s%f",ISBN,bookname,writername,publisher,&price);
		strcpy(L.elem[i].ISBN,ISBN);
		strcpy(L.elem[i].bookname,bookname);
		strcpy(L.elem[i].writername,writername);
		strcpy(L.elem[i].publisher,publisher);
		L.elem[i].price=price;
		i++;
	}
	L.length=i;
	fclose(fp);
}

void save(SqList L,char *filename)
{     //把信息保存到文件 
	FILE *fp;
	int i;
	if((fp=fopen(filename,"w"))==NULL){
		printf("文件不存在!\n");
		return ;
	} 
	for(i=0;i<L.length;i++){
		fprintf(fp,"%-15s\t%-30s\t%-10s\t%-20s\t%-6.2f\n",L.elem[i].ISBN,L.elem[i].bookname,L.elem[i].writername,L.elem[i].publisher,L.elem[i].price);
	}
	fclose(fp);
} 


int main(){
	int ch;
	SqList L;
	char ISBN[15],filename[30];
	int i;
	ElemType e;
	InitList_Sq(L);
	printf("1. 插入    2. 删除    3. 查找    4. 修改元素    5. 按ISBN排序元素    6. 输出    7. 导入    8. 保存    9. 退出\n");
	printf("请选择:");
	scanf("%d",&ch);
	while(ch!=9){
		switch(ch){
		case 1:   printf("请输入要增加的元素");
					scanf("%s%s%s%s%f",e.ISBN,e.bookname,e.writername,e.publisher,&e.price); 
					if(ListInsert_Sq(L,e)==OK){
						printf("插入成功!当前信息为:\n");
						print(L);
					}
					else {
						printf("表中已存在该图书!\n");
					} 
					break;
		case 2:   printf("请输入删除的图书ISBN:");
					scanf("%s",ISBN);
					if(ListDelete_Sq(L,ISBN,e)==OK)
					{
						printf("删除成功!被删图书为%s\t%s\t%s\t%s\t%.2f\n",e.ISBN,e.bookname,e.writername,e.publisher,e.price);
						print(L);
					}
					else
						printf("该图书不存在!\n");
					break;
		case 3:   printf("请输入要查找的图书ISBN:");
					scanf("%s",&ISBN);
					i=LocateElem_Sq(L,ISBN);
					if(i!=0)
					{
						printf("该图书为%s\t%s\t%s\t%s\t%.2f\n",L.elem[i-1].ISBN,L.elem[i-1].bookname,L.elem[i-1].writername,L.elem[i-1].publisher,L.elem[i-1].price);
					}
					else
						printf("该图书不存在!\n");
					break;
		case 4: printf("请输入要修改的图书ISBN:");
					scanf("%s",&ISBN);
					i=LocateElem_Sq(L,ISBN);
					if(i==0){
						printf("该图书不存在!\n");
					}   
					else{
						printf("请输入图书的ISBN,书名,主编,出版商和定价");
						scanf("%s%s%s%s%f",e.ISBN,e.bookname,e.writername,e.publisher,e.price);
						SetElem_Sq(L,i,e);
						printf("修改成功,图书信息为:");
						print(L);   
					}
					break;
		case 5:   sort_ISBN(L);
					printf("按照ISBN排序后\n");
					print(L);
					break;
		case 6: print(L);
					break;
		case 7: printf("请输入导入文件名:");
					scanf("%s",filename);
					import(L,filename);
					break;
		case 8: printf("请输入导出文件名:");
					scanf("%s",filename);
					save(L,filename);
					break;   
		default: printf("输入错误,请重新选择\n");
		}
		printf("1. 插入    2. 删除    3. 查找    4. 修改元素    5. 按ISBN排序元素    6. 输出    7. 导入    8. 保存    9. 退出\n");
			printf("请选择:");
			scanf("%d",&ch);
	}
} 

总结

该示例展示了如何使用C语言标准库完成基本的线性表操作及文件I/O。对于初学者而言,重点在于理解指针操作、内存动态分配以及结构体成员访问方式。以上就是关于C语言顺序表图书管理系统实现的详细内容,更多关于C语言数据结构实验的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。