利用CGI方式实现Web查询
发布时间:2005-03-28 浏览次数:1154387
出处:未知
作者:许玲
摘要:本文分析讨论了将WEB与后以数据源相连的方法之一——公共网关界面CGI的
概念与特点,并以成绩查询系统作为实例详细分析了用C语言进行CGI程序设计的方
法与过程。
关键词:CGI、Web集成
一CGI简述
公共网关界面(CGI)是一种编程标准,它规定了Web服务器调用其它可执行程序(CGI
程序)的接口协议标准。CGI程序通过Web服务器与运行Web服务器调用其它可执行程
序交互,它接受Web浏览器发送给Web服务器的信息,并进行处理,然后将结果再送
回给Web服务器及Web浏览器。CGI程序可以用任何程序设计语言编写,如Shell、
perl、C、Java等,用C语言编写的CGI程序具有速度快、性高等特点。CGI程序
通常用于加入查询机制、搜索机制、交互式应用及其它一些应用。
CGI接口标准包括输入、环境变量、标准输出三部分,CGI程序可以通过标准输入
(stdin)从Web服务器得到输入信息,例如从FORM中得到数据,这是常用的POST方
法。由于不同的操作系统采用了不同的信息交换机制,其参数传递的处理过程也有
差别,在Unix与DOS中,环境信息反映着本级程序运行时的某些系统状况,可用于父
程序与子程序间的信息传递,CGI正是通过设量环境变量在服务器与客户机间传递数
据的,各操作系统都提供了许多环境变量,它们定义了程序的执行环境,应用程序
可以存取它们。Web服务器和CGI接口也设置了一些环境变量用以传递一些重要的参
数。CGI程序通过标准输出(stdout)将输出信息传送给Web服务器,传送给服务器的
信息可以是HTML文本也可以是纯文本。本文将利用C语言编写一个CGI应用程序——
学生成绩查询系统,并分析了CGI程序设计的方法、过程、技巧。
二、成绩查询系统介绍
一个在WWW环境下的学生成绩公布栏必将成为日后各类成绩发布的主要手段,每位学
生交将有自己的密码,所以不必担心成绩上网之后的保密性。任何学生以任何形式
上网进入本站点的成绩查询系统之后,只要输入自己的系列、班别、学号及密码,
便可以利用这个学生绩查询系统查询自己的成绩,该设计思路与系统不仅适合各类
高校内部的成绩发布,也适合于高考、统考等大规模考试的成绩发布。本文介
绍的只是一个功能单一的查询系统,若需完善还需加入成绩维护部分,由成绩管理
者进行内容维护,包括成绩输入、修改、删除等功能。
三、HTML FORM格式部分
3.1 FORM输放的分解
在UNIX系统上,CGI信息是利用STDIN/STDOUT方式传输的,所以若要编写一个C语言
的CGI程序,必须要了解如何解剖与截取STDIN的CGI信息。当用户提交一个HTML
FORM时,WEB浏览器首先对FORM中的数据以名字/值对的形式进行编码,并发送给WEB
服务器,然后再由WEB服务器传递给CGI程序,其格式如下:
NAME1=VALUEL&NAME2=VALUE2&NAME3····
名字是FORM中定义的INPUT,SELECT等标置名字,值是用户输入或选择的标值,在程
序中将对其进行分析与解码,将其分解成一组组的名字/值对,这个过程是通过在输
入流中查找字符“=”与“&”来完成的,每当找到字符“=”,标志着一个FORM变量
名字的结束,当找到字符“&”,标志着一个FORM变量值的结束。当名字/值对分解
完之后,还须将输入中的一些特殊字符转换成相应的ASCII字符,如需将“+”转换
成空格符,将一些特殊字符转换成ASCII字符,对以上分所分析的分解与转换过程,
在下面的程序中有详细注明。
3.2HTML FORM文件
成绩查询系统的HTML文件P.htrnl
<TITLE>学生成绩查询系统</TITLE>
<H1>学生成绩查询系统</H1>
<FORM METHOD="POST"ACTION="URL地址"
<H3>系列:<SELECTNAME="Department">
<OPTION>计算机系
<OPTION>英语系
<OPTION>无线电系
</SELECT><P>
学号:<INPNT TYPE="TEXT"NAME="ID"><P>
密码:<INPNT TYPE="PASSWORD"NAME"PASSWORD"><P>
<INPNT TYPE="SUBMIT"VALUE"查询”>
<INPNT TYPE+"RESET"VALUE="放弃”〉
</FORM>
四、学生成绩查询CGI程序
该CGI程序分解、接收HTML FORM中提供的查询条件,然后查询出该学生的成绩并返
回。学生成绩有两个数据文件,一个是***SUB DAT,其中含有学生的各个科目,***
表示系别,如计算机系的科目文件是COMPSUB DAT,英语系的科目文件是
ENGSUB.DAT,无线电系科目文件是ELECSUB.DAT;另一个数据文件是***SCOER.DAT,
该文件中包含有每个学生的学号、密码与成绩,***表示系别,如计算机系的学生成
绩文件是COMPSCORE.DAT,同理,其他系的学生成绩文件按此原则以此类推。当学生
输入的学号及密码符合数据文件的内容时,会显示该学生的成绩。
main(int argc,char*argv[])
{
register int i,m=0;
int len;
FILE*fp,*fpl,*fopen();
char filename1[100],filename2[100],title[100];/*设定资料变量*/
char subject[10][10];
char id[100][10],password[100][10];
int score[100][],sum[100],allsum;
float avg[100],alltotalavg;
int rank,number,index,find,j,kind;
printf("content-type:text/html%c%c",10,10);
len=atoi(getenv("CONTENT_LENGITH"));
for(i=0;len && (!feof(stdin));i++){
m=i
inputs[i].val=readdstdin(stdin,&,&len);/*读STDiN信息*/
AddToSpace(inputs[i].val);
Convert(inputs[i].val);
inputs[i].name=ReadData(inputs[i].val,=);
}
strcpy(filename1,"/score/setup/");
stucpy(filename2,"/xcore/data/");
if(strcmp(inputs[o].val,"计算机系/)==0
strcat(filename1,"compusb.dat");
strcat(filename2,"compscore.dat");
}
if(strcmp(inputs[o].val,"英语系")==0
strcat(filenamel,"engsub.dat");
strcat(filename2,"engscore.dat");
}
if(strcmp(inputs[o].val,"无线电系")==0
}
strcat(filename1,"elecsub.dat");
strcat(filename2,"elecscore.dat");
}
fp=fopen(filename1,"r");/*打开文件*/
kind=0;
while(fscanf(fp,"%s",subject[kind]!=EOF
kind=kind+1;
fclose(fp);
fp1=fopen(filename2,"r");/*打开文件*/
allsum=0;
for(i=0;i<100;i++)
{
numbde=i;
if(fscanf(fp1,"%s%s",id[i],
password[i]!=EOF){
sum[i]=0;
for{j=0;j<kind;j++){
fscanf(fp1,"%d",&score[i][j]);
sum[i]+=score[i][j];
}
avg[i]=sum[i]/kind;
allsum+=sum[i];
}
else
break;
}
fclose(fp1);
find=0;
if(strcmp(inputs[2].val,id[i])==0&&
strcmp(inputs[3].val,password[i]==0){
index=i;
find=i;
}
}
if(find==0)
{
printf{"<H>输入有误,请再输一次!</h1>\n");
}
else
{
rank=1
for(i=o;i<number;i++)
if(sum[index]<sum[i])
rank=rank+1;
slltotalavg=allsum/number;
printf("<center><H1>学生成绩查询系统</H1></center>");
pritf("\n<center>查询学生学号:%s</center>
",
inputs[2].val);
printf("\n<center>成绩如下:</certer><hr>");
for(i=0;i<kind;i++)
printf{"%s\t",subject[kind]);
printf("总分
\n");
for(i=0;i<kind;i++)
printf("%d\t",score[index][i]);
printf["%d
\n",sum[index]);
}
}