[返回]
中国计算机报2001年第48期
自制“多功能收视指南表”
蔡畅奇
自动生成“多功能收视指南表”是一种新技术,它具有传统“收视指南表”或“收视指南系统”所不具有的优势,它便于后台人员维护、更新,还具有运行时占用内存小、速度快、安全性高等特点,本文将向大家介绍笔者设计的思路和方法。
传统“收视指南表”一般都是直接建立在html文本超链接上的,这使得用户查询起来非常不方便、不直观,而且增加了后台服务器的工作量、增大了维护工作的复杂性。为解决传统“电台收视指南表”的以上弊端,笔者利用C语言在Linux下开发了一个全新的“收视指南表”(以中央电视台为例的cgi程序),并实现了以下功能:
1.能够自动读取csv文件中的电台节目记录,并能按照记录中电台名称自动归类、按节目播出的时间段从前向后自动排序,这样录入者就可以随意追加或削减记录而不影响在浏览器上的显示。另外,csv文件可以在Windows的Excel中方便地加以录入,这些特点与传统的靠更换html页面来更新内容的方法相比大大减轻了维护人员的负担。
2.能将csv文件中读取并经过处理的记录以表格形式按不同电台分类、按播出时间段划分或按节目类型不同而加以颜色区分输出到网页上,同时每个节目名或者电台名均对应不同的超级链接(这些超链接在csv文件中已经对应输入),访问者单击这些节目名称或电台名称就可以链接到相应的网页上,方便访问者查询。程序运行原理如图所示。
3.由于整个程序由C语言开发并由gclearcase/" target="_blank" >cc编译,程序编译后的代码短小精悍,比其他语言(如Java、PHP)开发生成的程序运行速度要快20%~40%。
环境设置
开发环境:TurboLinux 6.0简体中文版、TurboLinux自带Apache服务器。
开发工具:gcc程序编译器、gdb程序调试器,编辑器建议用Linux操作系统中的文本编辑器。
在开发环境方面,主要是设置好Apache服务器,如果您使用的不是自带有Apache服务器Linux版本,你可到http://www.apache.org下载一份Apache服务器软件,并自行安装好。在开发工具方面,主要是使用gcc来编译程序,gdb用来进行检错调试。
注意事项
1.css文件是一种样式文件,在程序中要用到,请注意cgi的实际目录由于Linux的安全性,无法直接访问,请把css文件放置在Apahce 服务器的默认的目录下。TurboLinux操作系统中html文件读取目录默认为/home/httpd/html/,其他Linux操作系统可以从Apache服务器的conf文档srm.conf中找到相应目录,并且目录还可以修改。注意,主程序中链接的css文件的路径一定要设置正确。
2.在Windows的Excel中录入的csv文件,放置在Linux操作系统中可能会产生字符转换的问题,只要在Linux的文本中打开并保存即可解决,csv文件所存放的目录由主程序指定。
3.在Linux操作系统中调试C语言出现最多的问题就是所谓的“段错误”,这也是在调试程序中令人难于理解的地方,这种错误大多是由于指针错误造成内存泄漏所致(其特征是在当前目录下生成一个名字为core的内存映像文件),还有一种可能是Linux的高安全性造成的。前者请使用gdb加以调试,后者请将文件的属性设置安全度至少为755(#chmod 755表示所有用户有执行权,超级用户有所有权),有时还需更换目录。
设计要点
1.将存储记录的结构体定义成链表而不是数组,目的是为了实现动态存入记录。结构如下所示:
struct prog
{char ver[9];
char stat[35];
char year[20];
char month[5];
char date[3];
char start[6];
char end[6];
char prog[15];
int eol;
int block;
struct prog ?next;
};
2.读取每一条记录时需要设置循环(按一个字节方式)读取。并以“,”区分一个字符,以与换行符区分一个段落,实现链表中每个成员值的读取循环,如下所示:
case 1: for (i=0;i<=count;i++) {p1->ver[i]=buff[i]; p1->ver[i+1]='\0';}
3.链表中存入的记录需按电台名归类(名称相同的排在一起)并按节目播出时间段先后排序,目的是为了更新内容时方便输入记录。这两次排序是一个技术难点,关键问题是链表中结点的定位问题,这一点可以通过设置一个循环指针实现。在按节目播出时间段先后排序时要特别注意链表的指针,这是最容易出错的地方,要注意使用gdb调试。定位指针使其指向第k个结点的代码如下:
p4=head;
for(k1=1;k1<=k-1;k1++)
p4=p4->next;
4.在排序交换过程中需要通过设置循环来实现结点的交换,这里要多次用到链表结点定位方法。
5.Linux操作系统中程序在读取记录时可能会遇到数组无法存入较多的数据,如过长的超级链接字符串。这时请将超级链接分开存入,最后合成输出时即可。代码如下:
printf("<td class=%s colspan=%d width=%d>
<a class=%s href=\" %s%s \">%s</a></td>\n",p->ver,(muu(p->end)-muu(p->start))/30,
((muu(p->end)-muu(p->start))/30)?52,p->ver,ch1,p->stat,p->prog);
6.程序在输出“收视表”时需设置一个循环来实现。这里要注意的是设置好循环,加入是否是同一个电视台来区分段落的判断条件,特别需注意判断链表指针是否已经指向链表尾。我们可以按如下方式进行设计:
do
{
if(strcmp(p->year,(p->next)->year)==0)
printf("<td class=%s colspan=%d width=%d><a class=%s
href=\"%s%s\">%s</a></td>\n",p->ver,(muu(p->end)-muu(p->start))/30,((muu(p->end)-muu(p->start))/30)?52,p->ver,ch1,p->stat,p->prog);
else{
printf("<td class=%s colspan=%d width=%d><a class=%s
href=\"%s%s\">%s</a></td>\n",p->ver,(muu(p->end)-muu(p->start))/30,((muu(p->end)-muu(p->start))/30)?52,p->ver,ch1,p->stat,p->prog);
ch1=(p->next)->stat;
printf("</tr>\n");
printf("<tr valign=top>\n");
printf("<td class=station width=46>
<a class=station href=\"%s\"><b> %s</b></a></td>\n",(p->next)->stat,(p->next)->year);
p=p->next;
}
7.最后一点是要设计一个将字符串转换成整型数值的函数,因为在按节目播出时间先后排序与输出“收视表”中用到。此函数实现时最好使用指针来定位字符串中每一个字符,接着按C语言中字符所对应的ASCII十进制值计算即可实现。
与现有的技术相比,笔者的设计具有运行速度快、占用内存小及界面友好便于查询等优点,希望笔者设计开发的思路能为广大读者在开发类似软件时提供一些帮助。