cgic:为 C 语言编写 CGI 的 C 函数库 由 Thomas Boutell 开发 目录 CGIC 介绍 怎样写 CGIC 应用程序 怎样产生图片在 CGIC 中 ?
CGI 调试特征 :利用捕获 cgic 函数参考 cgic 变量参考 cgic 结果编码参考 cgic 快速索引 一般的 UNIX 系统都支持 ANSIC, 增加相应的库函数 ( 和相应的 h 文件 ) 就可以实现 CGI 。在此我向大家推荐一个用于 CGI 编程的 ANSIC 库 :cgic 。 cgic 是用来生成基于 CGI 的 WWW 应用程序的 C 语言函数库 , 它有以下功能 :
* 对数据进行语法分析 * 接收以 GET 和 PSOT 两种方式发送的数据 * 把 FORM 中的不同域连接成连续的串 *
为检索 FORM 数据而提供字符串 , 整数 , 浮点以及单项和多项选择功能 *
为数字字段提供边界检测 * 把 CGI 环境变量加载到非空的 C 串中 * 为调试而捕捉 CGI 状态 * 提供相对安全的系统调用功能
用一般 ANSI C 或 C++ 编译器就可以编译 cgic 程序 , 不过与通常 C 程序不同的是 , 用 cgic 写的源码其主函数是 cgiMain(), 而不是通常的 main() 。 cgic 的函数库会自动把 cgiMain 连接到相应的 main() 上去。 --------------------------------------------------------------------------------写 CGIC 程序 Note:所有的 cgic 应用程序必须连接 cgic.c.用 cgimain() 替代 main()必须包含: #include"cgic.h."基本结构 cgictest.c:
int
cgiMain() {
#if DEBUG
/* Load a saved CGI scenario if we're debugging */
cgiReadEnvironment("/path/to/capcgi.dat");
#endif
/* Important: we
must indicate the type of document */
cgiHeaderContentType("text/html");
/* Now invoke other functions to handle each part of the form */
fprintf(cgiOut, "\n");
fprintf(cgiOut,
"cgic test\n"):
fprintf(cgiOut,
"
cgic test\n");
Name();
Address();
Hungry();
Temperature();
Frogs();
Color();
Flavors();
NonExButtons();
RadioButtons();
fprintf(cgiOut,
"
\n");
/* This value will be the exit code of the
program; 0
generally indicates success among Unix and DOS programs */
return 0;
}
capture输出标头 cgiHeaderContentType() 在输出文挡之前简要说明 MIME 内型 , 如 "text/html" 。 cgiHeaderStatus()
代替输出错误代码 cgiHeaderLocation() 代替重新引导至其他页面。在一个独立的应用程序中只能有一个 cgiHeader 函数。 重点 : 在 cgiHeader 函数组中, cgiHeaderContentType(),在任何向浏览器输出之前被调用 .否则将出错或浏览器不能识别。 cgiOut接着 ,
cgiMain()调用不同的函数 . 当函数结束后 , 将返回 0处理输入文本 void Name() {
char name[81];
cgiFormStringNoNewlines("name", name, 81);
fprintf(cgiOut, "Name:
%s
\n", name);
}这个函数的功能就是取的并显示由用户输入的 name .处理输出 Important: cgiOut 通常相当于 stdout
cgiFormString确保断航 处理单一 Checkboxes 输入 这个 Hungry() function 确定用户是否选择 "hungry" 这个 checkbox:
void Hungry() {
if (cgiFormCheckboxSingle("hungry") == cgiFormSuccess) {
fprintf(cgiOut,
"I'm Hungry!
\n");
} else {
fprintf(cgiOut, "I'm Not
Hungry!
\n");
}
}这个函数依靠 cgiFormCheckboxSingle()确定单一的 checkbox被选择。 cgiFormCheckboxSingle()接受 checkbox 名字的属性值,如果存在就返回 cgiFormSuccess ,否则返回
cgiFormNotFound如果是多项 checkboxes ,就用 cgiFormCheckboxMultiple() 和 cgiFormStringMultiple()函数 .处理数字输入 Temperature()返回浮点书的值确保在特定的返回内。 void
Temperature() {
double temperature;
cgiFormDoubleBounded("temperature",
&temperature, 80.0, 120.0, 98.6);
fprintf(cgiOut, "My temperature is
%f.
\n", temperature);
}依靠 cgiFormDoubleBounded()
得到数据 . 第一个数据是返回数据中输入域的名字。最后一个值是用户没有提交时的默认值。 这个函数总是找回在特定返回内合适的值
; cgiFormDoubleBounded 返回的值被检查确信用户输入的资料在规定范围内, 而不是其他无效的数据。查看 cgiFormDoubleBounded()更多的资料 .如果限度检查不理想,可以用 cgiFormDouble()替代 .在整数输入 ,cgiFormInteger和 cgiFormIntegerBounded可以利用 .这些函数的功能类似 .处理单一选择输入 HTML 标签被用于向用户提供几个选择 . Radio buttons和 checkboxes椰油这样的用途,大门、能够选择的数量很小时 . Color()
char *colors[] = {
"Red",
"Green",
"Blue"
};
void
Color() {
int colorChoice;
cgiFormSelectSingle("colors", colors, 3,
&colorChoice, 0);
fprintf(cgiOut, "I am: %s
\n",
colors[colorChoice]);
}这个函数确定用户选择了几个选项从 在表但的列表 .
cgiFormSelectSingle()
cgiFormSelectSingle()总是显示合理的选项值 .
radio
button 也可以用这个函数 . 另外还有 cgiFormRadio(),也是一样的
处理多项选择的输入 NonExButtons()
char *votes[] = {
"A",
"B",
"C",
"D"
};
void
NonExButtons() {
int voteChoices[4];
int i;
int result;
int
invalid;
char **responses;
/* Method #1: check for valid votes.
This is a good idea,
since votes for nonexistent candidates should probably
be discounted... */
fprintf(cgiOut, "Votes (method 1):
\n");
result = cgiFormCheckboxMultiple("vote", votes, 4,
voteChoices,
&invalid);
if (result == cgiFormNotFound) {
fprintf(cgiOut, "I hate
them all!
\n");
} else {
fprintf(cgiOut, "My preferred
candidates are:\n");
fprintf(cgiOut, "\n");
for (i=0; (i <
4); i++) {
if (voteChoices[i]) {
fprintf(cgiOut, "
%s\n",
votes[i]);
}
}
fprintf(cgiOut, "\n");
}参考 cgiFormCheckboxMultiple(), cgiFormSelectMultiple().
cgiFormCheckboxMultiple() cgiFormCheckboxMultiple
NonExButtons()函数在 cgictest.c:
/* Method #2: get all the names voted for and trust them.
This is
good if the form will change more often
than the code and invented responses
are not a danger
or can be checked in some other way. */
fprintf(cgiOut,
"Votes (method 2):
\n");
result = cgiFormStringMultiple("vote",
&responses);
if (result == cgiFormNotFound) {
fprintf(cgiOut, "I
hate them all!
\n");
} else {
int i = 0;
fprintf(cgiOut, "My
preferred candidates are:\n");
fprintf(cgiOut, "\n");
while
(responses[i]) {
fprintf(cgiOut, "
%s\n", responses[i]);
i++;
}
fprintf(cgiOut, "\n");
}
/* We must be sure to free
the string array or a memory
leak will occur. Simply calling free() would
free
the array but not the individual strings. The
function
cgiStringArrayFree() does the job completely. */
cgiStringArrayFree(responses);
}参考 cgiFormStringMultiple()
cgiFormStringMultiple()
/* An array of strings; each C string is an
array of characters */
char **responses;
cgiFormStringMultiple("vote", &responses);检查 CGI 环境变量 将用到的变量 这里
,产生图象 #include "cgic.h"
#include "gd.h"
char *colors[]
= {
"red", "green", "blue"
};
#define colorsTotal 3
int
cgiMain() {
int colorChosen;
gdImagePtr im;
int r, g, b;
/* Use
gd to create an
image */
im = gdImageCreate(64, 64);
r = gdImageColorAllocate(im, 255,
0, 0);
g = gdImageColorAllocate(im, 0, 255, 0);
b =
gdImageColorAllocate(im, 0, 0, 255);
/* Now use cgic to find out what color
the user requested */
cgiFormSelectSingle("color", 3, &colorChosen, 0);
/* Now fill with the desired color */
switch(colorChosen) {
case 0:
gdImageFill(im, 32, 32, r);
break;
case 1:
gdImageFill(im, 32,
32, g);
break;
case 2:
gdImageFill(im, 32, 32, b);
break;
}
/* Now output the image. Note the content type! */
cgiHeaderContentType("image/gif");
/* Send the image to cgiOut */
gdImageGif(im, cgiOut);
/* Free the gd image */
gdImageDestroy(im);
return 0;
}为调试而捕捉CGI
状态cgic 函数参考cgiFormResultType
cgiFormString( char *name, char *result, int max)用于从输入域中copy 字符串。他将域名max-1 字节中的字符copy 到缓冲区result 。若域不存在,则copy 一个空串到result
缓冲区。在此函数中所有的新行由换行符代表。cgiFormResultType
cgiFormStringNoNewlines( char *name, char *result, int max)它与cgiFormString 函数相似,只是所有的CR 和LF 都被去掉了。cgiFormResultType
cgiFormStringSpaceNeeded( char *name, int *length)它返回指向name 的字符串的长度,并将长度放入length 中。cgiFormResultType cgiFormStringMultiple( char *name, char
***ptrToStringArray)若同一名字有多个输入域,或域中的字符串可以动态变化,那么你可以使用本函数。它把名为name 的所有输入域的值放在prtToStringArray
中。void cgiStringArrayFree(char **stringArray)它释放了分配给stringArray 的内存。cgiFormResultType cgiFormInteger( char *name, int *result, int defaultV)从输入域中取出整数放入result 中。cgiFormResultType cgiFormIntegerBounded( char *name, int *result, int
min, int max, int defaultV)若输入域中的整数在界限内则取出并放入result 中。cgiFormResultType
cgiFormDouble( char *name, double *result, double defaultV)从输入域中取出浮点数放入result 中。cgiFormResultType cgiFormDoubleBounded( char *name, double *result,
double min, double max, double defaultV)若输入域中的浮点数在界限内则取出并放入result 中。cgiFormResultType
cgiFormSelectSingle( char *name, char **choicesText, int choicesTotal, int
*result, int defaultV)取出复选框( 跟在select 语句之后的) ,把选择的名字copy 到choicesText ,把选择的个数copy 到choicesTotal ,把当前的选择copy 到result 。cgiFormResultType cgiFormSelectMultiple( char *name, char **choicesText, int
choicesTotal, int *result, int *invalid)与cgiFormSelectSingle 类似,只指向整型数组的result
代表了选择的项。cgiFormResultType cgiFormCheckboxSingle( char
*name)若复选框被选中,则函数返回cgiFormSuccess ,否则返回cgiFormNotFound 。cgiFormResultType
cgiFormCheckboxMultiple( char *name, char **valuesText, int valuesTotal, int
*result, int *invalid)