一、实验题目
图书信息管理系统
出版社有一些图书数据,为简单起见,在此假设每种图书只包括三部分信息:ISBN (书号)、书名和价格,文件中的部分数据如图2.1所示。现要求实现一个图书信息管理系统,包括以下6个具体功能。
(1)查找:根据指定的ISBN或书名查找相应图书的有关信息,并返回该图书在表中的位置序号。
(2)插入:插入一种新的图书信息。
(3)删除:删除一种图书信息。
(4)修改:根据指定的ISBN,修改该图书的价格。
(5)排序:将图书按照价格由低到高进行排序。
(6)计数:统计图书表中的图书数量。
二、工具环境
Window10操作系统,Microsoft Visual C++2010学习版 集成开发环境,C语言
三、实验问题
在指针未初始化时,在自定义函数里初始化需要用到二级指针,否则函数内的指针和主函数里的指针地址不一样,malloc分配时不是给主函数指针分配;用二级指针时,在自定义函数内遇到无法进行初始化后赋值 (下面代码简写)
问题:
#include<stdio.h>
#include<stdlib.h>
#define N 100
typedef struct {
int num;//序号
char ISBN[20];
char name[N+1];
int price;
}Book;
typedef struct {
Book *book;
int length;
}SqList;
int InitList(SqList **L,Book *book)
{
*L=(SqList *)malloc(1*sizeof(SqList));//初始化正确√
*L->book=book;//初始化后赋值出现错误×
*L->length=1; //初始化后赋值出现错误×
return 0;
}
int main()
{
SqList *L=NULL;
Book book[MAXSIZE]={
{1,"9787302257646","程序设计基础",25}
};
InitList(&L,book)//初始化
return 0;
}
编译会出
error C2223: “->book”的左侧必须指向结构/联合
四、实验代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAXSIZE 50 // 最多图书数
#define N 100
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;
typedef struct {
int num;//序号
char ISBN[20];
char name[N+1];
int price;
}Book;
typedef struct {
Book *book;//存储空间的基地址
int length;//图书表中当前图书个数
}SqList;//图书表的顺序存储结构类型为sqList
Status InitList(SqList **L,Book *book); //初始化
Status LocateElem(SqList *L,char ISBN[],char name[]);//查找
Status Listinsert(SqList *L); //插入
Status ListDelete(SqList *L); //删除
Status ListAlter(SqList *L); //修改
Status ListOrder(SqList *L); //排序
void showbook(SqList *L);
int main()//---------------------------------主函数---------------------------------
{
SqList *L=NULL;
//Book *book=(Book *)malloc(MAXSIZE*sizeof(Book));
Book book[MAXSIZE]={
{1,"9787302257646","程序设计基础",25},
{2,"9787302219972","单片机技术及应用",32},
{3,"9787302203513","编译原理",46},
{4,"9787811234923","汇编语言程序设计教程",21},
{5,"9787512100831","计算机操作系统",17},
{6,"9787302265436","计算机导论实验指导",18},
{7,"9787302180630","实用数据结构",29},
{8,"9787302225065","数据结构(C语言版)",38},
{9,"9787302171676","C#面向对象程序设计",39},
{10,"9787302250692","C语言程序设计",42},
{11,"9787302150664","数据库原理",35},
{12,"9787302260806","Java编程与实践",56},
{13,"9787302252887","Java程序设计与应用教程",39},
{14,"9787302198505","嵌入式操作系统及编程",25},
{15,"9787302169666","软件测试",24},
{16,"9787811231557","Eclipse基础与应用",35},
};
char ISBN[50];
char name[50];
int i;
system("color f1");
InitList(&L,book);//初始化
printf("\t------------------------------------\n");
printf("\t——欢迎使用图书信息管理系统——\n");
printf("\t0. 退出学图书信息管理系统\n");
printf("\t1. 查找图书\n");
printf("\t2. 添加图书\n");
printf("\t3. 删除图书\n");
printf("\t4. 修改图书\n");
printf("\t5. 按图书价格排序\n");
printf("\t6. 统计图书数量\n");
showbook(L);//显示所有图书信息
while(1)
{
int choose;
printf("\n\t请输入你要选择的功能前的序号:");
scanf("%d",&choose);
if(choose==0){
printf("\n\t退出成功,谢谢使用图书信息管理系统!");
break;
}
switch(choose)
{
case 1://"1. 查找图书\n");
LocateElem(L,ISBN,name);
break;
case 2://"2. 添加图书\n");
Listinsert(L);
break;
case 3://3. 删除图书\n");
ListDelete(L);
break;
case 4://4. 修改图书\n");
ListAlter(L);
break;
case 5://5. 按图书价格排序\n");
ListOrder(L);
break;
case 6://6. 统计图书数量\n");
printf("\n\t共有%d本图书\n",L->length);
break;
}
}
return 0;
}//---------------------------------主函数---------------------------------
Status InitList(SqList **L,Book *book)
{
*L=(SqList *)malloc(1*sizeof(SqList));
(*L)->book=book;
(*L)->length=16;
return OK;
}
Status LocateElem(SqList *L,char ISBN[],char name[])
{
int choose=0,i,flag=0;//flag=1说明选择方式正确;flag=-1说明查找到图书
printf("\n\t请选择查找图书的方式: 1.按ISBN查找,2.按书名查找:\n");
printf("\t请输入:");
scanf("%d",&choose);
while(flag!=1){
switch(choose){
case 1:
printf("\t请输入要查找图书的ISBN:");
scanf("%s",ISBN);
for(i=0;i<L->length;i++){
if(strcmp(ISBN,L->book[i].ISBN)==0){
printf("\n\t查找到ISBN为%s的图书序号为%d\n",ISBN,L->book[i].num);
flag=-1;
break;
}
}
if(flag!=-1)
printf("\n\t不存在该图书\n");
flag=1;
break;
case 2:
printf("\t请输入要查找图书的名字:");
scanf("%s",name);
for(i=0;i<L->length;i++){
if(strcmp(name,L->book[i].name)==0){
printf("\n\t查找到名字为%s的图书序号为%d\n",name,L->book[i].num);
flag=-1;
break;
}
}
if(flag!=-1)
printf("\n\t不存在该图书\n");
flag=1;
break;
default:
printf("\n\t请重新输入:");
scanf("%d",&choose);
break;
}
}
return OK;
}
Status Listinsert(SqList *L)
{
char ISBN[20],name[N+1];int price,length=L->length;
if(length==MAXSIZE) return ERROR;
printf("\t请输入要添加的图书信息:\n");
printf("\t请输入图书的ISBN:");scanf("%s",ISBN);
printf("\t请输入图书的名字:");scanf("%s",name);
printf("\t请输入图书的价格:");scanf("%d",&price);
strcpy(L->book[length].ISBN,ISBN);
strcpy(L->book[length].name,name);
L->book[length].price=price;
L->book[length].num=length+1;
L->length++;
printf("\n\t添加成功\n");
return OK;
}
Status ListDelete(SqList *L)
{
int i,j,num,flag=0,length=L->length;
char ISBN[20];
printf("\t请输入你要删除的图书的ISBN:");scanf("%s",ISBN);
for(i=0;i<length;i++){
if(strcmp(ISBN,L->book[i].ISBN)==0){
j=L->book[i].num-1;
flag=1;
break;
}
}
if(flag!=1)
{
printf("\n\t找不到此图书\n");
return ERROR;
}else{
for (;j<length-1;j++){
L->book[j]=L->book[j+1];
L->book[j].num=j+1;
}
L->length--;
printf("\n\t删除成功\n");
return OK;
}
}
Status ListAlter(SqList *L)
{
int i,choose,price,flag=0,length=L->length;
char ISBN[20],name[N+1];
printf("\t请输入你要修改的图书的ISBN:");scanf("%s",ISBN);
for(i=0;i<length;i++){
if(strcmp(ISBN,L->book[i].ISBN)==0){
flag=1;
break;
}
}
if(flag==1){
while(1)
{
printf("\t0. 退出修改\n");
printf("\t1. 修改ISBN\n");
printf("\t2. 修改名字\n");
printf("\t3. 修改价格\n");
printf("\n\t请输入你要选择的功能前的序号:");
scanf("%d",&choose);
if(choose==0) break;
switch(choose)
{
case 1://"1. 修改ISBN");
printf("\t请输入图书的ISBN:");scanf("%s",ISBN);
strcpy(L->book[i].ISBN,ISBN);
break;
case 2://"2. 修改名字");
printf("\t请输入图书的名字:");scanf("%s",name);
strcpy(L->book[i].name,name);
break;
case 3://3. 修改价格");
printf("\t请输入图书的价格:");scanf("%d",&price);
L->book[i].price=price;
break;
}
}//while
printf("\n\t修改成功\n");
}else{
printf("\t找不到此图书\n");
return ERROR;
}
return OK;
}
Status ListOrder(SqList *L){
int i,j,length=L->length;
Book temp;
for(i=0;i<length;i++)//按价格排序
{
for(j=i+1;j<length;j++)
{
if(L->book[i].price> L->book[j].price ){
temp=L->book[i];
L->book[i]=L->book[j];
L->book[j]=temp;
}
}
}
printf("\n\t序号\t\tISBN\t\t名字\t\t\t价格\n");
for(i=0;i<length;i++)
{
printf("\t %d \t %-13s \t %-22s \t %d\n",L->book[i].num,L->book[i].ISBN,L->book[i].name,L->book[i].price);
}
for(i=0;i<length;i++)//恢复按序号排序
{
for(j=i+1;j<length;j++)
{
if(L->book[i].num> L->book[j].num ){
temp=L->book[i];
L->book[i]=L->book[j];
L->book[j]=temp;
}
}
}
return OK;
}
void showbook(SqList *L)
{
int i;
printf("\t---------------------------------------------------------------\n");
printf("\t序号\t\tISBN\t\t名字\t\t\t价格\n");
for(i=0;i<L->length;i++)
{
printf("\t %d \t %-13s \t %-22s \t %d\n",L->book[i].num,L->book[i].ISBN,L->book[i].name,L->book[i].price);
}
printf("\t---------------------------------------------------------------\n");
}
五、解决方法
方法:
在(*L)处添加括号
#include<stdio.h>
#include<stdlib.h>
#define N 100
typedef struct {
int num;//序号
char ISBN[20];
char name[N+1];
int price;
}Book;
typedef struct {
Book *book;
int length;
}SqList;
int InitList(SqList **L,Book *book)
{
*L=(SqList *)malloc(1*sizeof(SqList));//初始化正确√
(*L)->book=book;//初始化后赋值正确√
(*L)->length=1; //初始化后赋值正确√
return 0;
}
int main()
{
SqList *L=NULL;
Book book[MAXSIZE]={
{1,"9787302257646","程序设计基础",25}
};
InitList(&L,book)//初始化
return 0;
}
问题应该是 * 和 -> 符号优先级的问题,平时没有注意,写的时候发现在自定义函数内用二级指针初始化指针并赋值的时候要加括号。