作者:刘晓兵
语言:C语言,主要是对链表的操作,其次是对数据库进行“读”、“删”、“存”操作
环境:Linux下gcc编译器
数据库:MySQL
1、链表:
没什么好说的,不会的话照着书上敲几个代码看懂就会了!
几个值得注意的地方(我遇到的问题):
(1)malloc_usable_size(p)
用free(p)释放内存,怎样知道你的free(p)起作用了?真正释放了?
在Linux下gcc编译器中用malloc_usable_size(p)可以计算指针p所指向的内存区大小(好像有点偏大);
在windows下用_msize(p)可以比较准确的计算指针p所指向的内存区大小
eg:
/////////////////////////////////////////////////////////////////////////////
int len = malloc_usable_size(p1); /*释放前p1占用的空间长度*/
free(p1); /*释放p1指向的空间*/
int alen = malloc_usable_size(p1);/*释放后p1占用的空间长度*/
printf("%d %d/n",len,alen);/*打印出释放前后的对比效果*/
//////////////////////////////////////////////////////////////////////////////
(2)字符串的赋值函数 strncpy
strncpy(m,n,sizeof(n));
值得注意的是sizeof对指针数组而言,她的值永远是4!
eg:
//////////////////////////////////////////////////////////////////////////////
char *m="liudehua";
char n[120];
strncpy( n, m, sizeof(m));//错误赋值,得不到想要的,只能将"liud"赋给n;
strncpy( n, m, 10);//赋值正确,可以将"liudehua"赋给n,但这样可能会浪费资源(暂时没有不知道有什么好方法可以解决这个问题)
///////////////////////////////////////////////////////////////////////
2、C连接数据库:
eg:(注:本例数据库的用户名root,密码123456,数据库student)
////////////////////////////////////////////////////////////////////////////////
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"/usr/include/mysql/mysql.h" /*此处对应相应文件的具体位置,根据具体情况而定,下两行同此*/
#include "/usr/include/mysql/mysql_version.h"
#include "/usr/include/mysql/errmsg.h"
MYSQL*stumysql;
int main()
{
stumysql=mysql_init(NULL); /*实现数据库连接*/
if(mysql_real_connect(stumysql,"localhost","root","123456","student",0,NULL,0))
{
printf("Connect Successfully!数据库连接成功!/n");
}
else
{
printf("Connect Failed!数据库连接失败!/n");
}
mysql_close(stumysql); /*关闭数据库*/
}
//////////////////////////////////////////////////////////////////////////////////////
将上面的文件保存为mysqlconnect.c
执行编译命令:gcc -o mysqlconnect mysqlconnect.c -L/usr/lib/mysql/ -lmysqlclient -lz
然后运行(./mysqlconnect)即可。
3、Makefile:
上面的C连接数据库的Makefile文件可以这样写(注意:有gcc的那两行前面一定要加Tab键):
mysqlconnect:mysqlconnect.o
gcc -o mysqlconnect mysqlconnect.o -L/usr/lib/mysql/ -lmysqlclient -lz
mysqlconnect.o:mysqlconnect.c /usr/include/mysql/mysql.h /usr/include/mysql/mysql_version.h /usr/include/mysql/errmsg.h
gcc -c mysqlconnect.c
clean:
rm -f *.o
附: 我写的学生管理系统代码(初学水平):
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#include<string.h>
#include"/usr/include/mysql/mysql.h"
#include "/usr/include/mysql/mysql_version.h"
#include "/usr/include/mysql/errmsg.h"
#define LEN sizeof(struct student)
MYSQL*stumysql;
MYSQL_RES*stures;
MYSQL_ROW row;
struct student
{
int num;
char name[12000];
float score1;
float score2;
float everange;
struct student *next;
};
struct student *head;
int n;
void insert_stu(); /*添加信息*/
void delete_stu(); /*删除信息*/
void modify_stu(); /*修改信息*/
void selecte_stu(); /*查看个人信息*/
void everange_stu();/*计算平均分*/
void save_stu(); /*保存*/
void save(); /*保存到数据库*/
void print(); /*输出head的函数*/
void logout(); /*退出*/
void switch_stu(); /*主菜单*/
/*main.c*/
int main()
{
struct student *p1,*p2;
int j;
unsigned long i;
n=0;
stumysql=mysql_init(NULL); /*实现数据库连接*/
if(mysql_real_connect(stumysql,"localhost","root","123456","student",0,NULL,0))
{
printf("Connect Successfully!数据库连接成功!/n");
}
else
{
printf("Connect Failed!数据库连接失败!/n");
}
if(!mysql_query(stumysql,"select * from stu_info order by num"))
{
stures=mysql_store_result(stumysql);
i=mysql_num_rows(stures);
p1=p2=( struct student* )malloc(LEN);
head = NULL;
for(j=0;j<i;j++)
{
row=mysql_fetch_row(stures);
p1->num = atoi(row[1]);
strncpy(p1->name,row[2],15);
//printf("%s,%s/n",row[2],p1->name);
p1->score1 = atof(row[3]);
p1->score2 = atof(row[4]);
p1->everange = atof(row[5]);
n=n+1;
if(n==1)
{
head=p1;
}
else
{
p2->next=p1;
}
p2=p1;
p1=(struct student *)malloc(LEN);
}
p2->next=NULL;
}
print(head);
switch_stu();
mysql_close(stumysql);
//printf("mysql close");
return 0;
}
/*switch_stu()*/
void switch_stu()
{
int a;
printf("请选择您要进行的操作:/n");
printf("1、插入信息 2、删除信息 3、修改信息(按学号)/n");
printf("4、查看个人信息(按学号) 5、保存信息 0、退出系统/n输入相应序号进行操作:");
scanf("%d",&a);
switch(a)
{
case 0:
{
//printf("退出系统/n");
logout();
break;
}
case 1:
{
insert_stu();
break;
}
case 2:
{
delete_stu();
break;
}
case 3:
{
//printf("modify_stu/n");
modify_stu();
break;
}
case 4:
{
//printf("everange_stu/n");
selecte_stu();
break;
}
case 5:
{
//printf("save/n");
save_stu();
break;
}
default :
{
printf("输入有误!重新输入:/n");
switch_stu();
}
}
}
/*print.c*/
void print(struct student * head)
{
struct student *p;
printf("/n现在有%d条记录 :/n",n);
printf("num name score1 score2 everange/n");
p=head;
if(head!=NULL)
while(p!=NULL)
{
printf("%1d %-12s %-6.1f %-6.1f %-6.1f/n",p->num,p->name,p->score1,p->score2,p->everange);
p=p->next;
}
}
/*insert_stu()*/
void insert_stu()
{ struct student *stud;
struct student *p0,*p1,*p2 = NULL;
printf("请输入信息(以一个或多个空格隔开,输入0_0_0_0返回主界面):/nnum name score1 score2/n");
stud=(struct student *)malloc(LEN);
scanf("%ld %s %f %f",&stud->num,&stud->name,&stud->score1,&stud->score2);
if(stud->num != 0)
{
p1=head;
p0=stud;
if(head==NULL)
{
head=p0;
p0->next=NULL;
}
else
{
while((p0->num > p1->num)&&(p1->next!=NULL))
{
p2=p1;
p1=p1->next;
}
if(p0->num < p1->num)
{
if(head==p1)
head=p0;
else
p2->next=p0;
p0->next=p1;
}
else if(p0->num > p1->num)
{
p1->next=p0;
p0->next=NULL;
}
else if(p0->num == p1->num)
{
printf("您输入的学号已经存在,返回/n");
print(head);
switch_stu();
goto end;
}
}
n=n+1;
everange_stu();
goto end;
}
else
{
switch_stu();
goto end;
}
end:
printf("");
}
/*delete_stu()*/
void delete_stu()
{
int num;
struct student *p1,*p2;
printf("请输入要删除的学号:/n");
scanf("%d",&num);
if (head==NULL)
{
printf("/nlist null!/n");
goto end;
}
p1=head;
while(num!=p1->num && p1->next!=NULL)
{
p2=p1;p1=p1->next;
}
if(num==p1->num)
{
if(p1==head) /*释放头结点*/
{
head=p1->next;
int len = malloc_usable_size(p1); /*释放前占用的空间长度*/
free(p1); /*释放p1指向的空间*/
//int lenn = malloc_usable_size(p1);/*释放后占用的空间长度*/
//printf("%d %s %d/n",len,p1->name,lenn);/*打印出释放前后的对比效果*/
printf("释放的空间有:%d/n",len);
}
else /*释放非头结点*/
{
p2->next=p1->next;
int alen = malloc_usable_size(p1);/*释放前占用的空间长度*/
free(p1); /*释放*/
//int alenn = malloc_usable_size(p1);/*释放后占用的空间长度*/
//printf("%d %s %d/n",alen,p1->name,alenn);/*打印出释放前后的对比效果*/
printf("释放的空间有:%d/n",alen);
}
printf("删除%d成功!/n",num);
n=n-1;
}
else
printf("学号%d不存在!/n",num);
end:
//return (head);
print(head);
switch_stu();
}
/*modify_stu()*/
void modify_stu()
{
int num;
struct student *p1,*p2;
printf("请输入学号以修改相应信息:/n");
scanf("%d",&num);
if (head==NULL)
{
printf("/nlist null!/n");
goto end;
}
p1=head;
while(num!=p1->num && p1->next!=NULL)
{
p2=p1;p1=p1->next;
}
if(num==p1->num)
{
if(p1==head) /*释放头结点*/
{
head=p1->next;
//int len = malloc_usable_size(p1); /*释放前占用的空间长度*/
free(p1); /*释放p1指向的空间*/
//int lenn = malloc_usable_size(p1);/*释放后占用的空间长度*/
//printf("%d %s %d/n",len,p1->name,lenn);/*打印出释放前后的对比效果*/
//printf("释放的空间有:%d/n",len);
}
else /*释放非头结点*/
{
p2->next=p1->next;
//int alen = malloc_usable_size(p1);/*释放前占用的空间长度*/
free(p1); /*释放*/
//int alenn = malloc_usable_size(p1);/*释放后占用的空间长度*/
//printf("%d %s %d/n",alen,p1->name,alenn);/*打印出释放前后的对比效果*/
}
//printf("删除%d成功!/n",num);
n=n-1;
insert_stu();
}
else
printf("学号%d不存在!/n",num);
end:
printf("");
}
/*selecte_stu()*/
void selecte_stu()
{
int num;
struct student *p1,*p2;
printf("请输入学号:");
scanf("%d",&num);
if (head==NULL)
{
printf("/n没有信息!/n");
goto end;
}
p1=head;
while(num!=p1->num && p1->next!=NULL)
{
p2=p1;p1=p1->next;
}
if(num==p1->num)
{
printf("%ld %-10s %5.1f %5.1f %5.1f/n",p1->num,p1->name,p1->score1,p1->score2,p1->everange);
}
else
printf("学号%d不存在!/n",num);
end:
switch_stu();
}
/*everange_stu()*/
void everange_stu()
{
int j;
struct student *p1,*p2;
if ( head == NULL)
{
printf("链表为空!退出!");
goto end ;
}
p1 = head;
for ( j=0; j < n; j++)
{
p1->everange = (p1->score1 + p1->score2) / 2;
p2 = p1;
p1 = p1->next;
}
end:
print(head);
switch_stu();
}
/*save_stu()*/
void save_stu()
{
save();
switch_stu();
}
/*logout()*/
void logout()
{
int a,j;
struct student *p1;
printf("退出前是否保存?1保存/0直接退出/n");
scanf("%d",&a);
if( a!=0 )
{
save();
printf("已经存入数据库!/n");
}
for( j=0; j < n; j++ )
{
p1 = head;
head=p1->next;
//int len = malloc_usable_size(p1); /*释放前占用的空间长度*/
free(p1); /*释放p1指向的空间*/
//int lenn = malloc_usable_size(p1);/*释放后占用的空间长度*/
//printf("%d %s %d/n",len,p1->name,lenn);/*打印出释放前后的对比效果*/
//printf("释放的空间有:%d/n",len);
}
printf("退出成功!/n");
}
/*save()*/
void save()
{
int a,j;
char query[256];
struct student *p1,*p2;
if (head == NULL)
{
printf("链表为空,是否清空数据表!(1清空/0取消)/n");
scanf("%d",&a);
printf("%d/n",a);
if( a == 1)
{
if(!mysql_query(stumysql,"TRUNCATE TABLE stu_info"))
{
printf("数据表stu_info已经清空!/n");
}
}
else if( a == 0)
{
printf("返回/n");
goto end;
}
}
p1 = head;
/*if(!mysql_query(stumysql,"TRUNCATE TABLE stu_info"))
{
printf("数据表stu_info已经清空!/n");
}*/
mysql_query(stumysql,"TRUNCATE TABLE stu_info");
for ( j=0; j < n; j++)
{
sprintf(query,"insert into stu_info(num,name,score1,score2,everange) values('%ld','%s','%5.1f','%5.1f','%5.1f')",p1->num,p1->name,p1->score1,p1->score2,p1->everange);
//printf("%s/n",query);
mysql_query (stumysql,query);
p2 = p1;
p1 = p1->next;
}
printf("保存成功!数据已经存入数据库!/n");
end:
print(head);
}