我在下面有以下HTML代码。
<html>
<head><title>OPTIONS</title></head>
<body>
<p>Choose schedule to generate:</p>
<form action='cgi-bin/mp1b.cgi' method="get">
<input type=checkbox value='tfield' name=on />Teacher<input type=text name="teacher" value=""/><br>
<input type=checkbox value='sfield' name=on />Subject<input type=text name="subject" value=""/><br>
<input type=checkbox value='rfield' name=on />Room<input type=text name="room" value=""/><br>
<input type=submit value="Generate Schedule"/>
</form>
</body>
</html>
我有这个用C编写的CGI脚本:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
char *data = malloc(1024);
char teacher[1024];
char subject[1024];
char room[1024];
printf("Content-type:text/html\n\n");
printf("<html><body>");
data = getenv("QUERY_STRING");
if(data){
sscanf(data,"teacher=%s&subject=%s&room=%s",teacher,subject,room);
printf("%s,%s,%s",teacher,subject,room);
}
printf("</body></html>");
return 0;
}
每当我点击“提交”按钮时,都会输出
(空),A ...,OEI
我的代码出了什么问题?谢谢!
已编辑:代码已编辑但输出:
史密斯&安培受试者=物理与安培;房间=房间,XOM·升,
答案 0 :(得分:0)
您最初没有为teacher
,subject
和room
分配内存。你修正了固定大小的块;这是一个解决方案,当你100%确定你的字符串永远不会变得更长时(也是在奇怪的错误情况下)。
您不需要为data
分配内存。
char*
只不过是指向字符串的指针;它没有实际char
的任何存储空间。
你可以这样做:
...
data = getenv("QUERY_STRING");
teacher = malloc(strlen(data) + 1);
subject = malloc(strlen(data) + 1);
room = malloc(strlen(data) + 1);
获取永远足够的内存块。别忘了free()
。
另外,请检查sscanf()
的返回值,它应该是3
。在您的情况下,它返回1,因为scanf()
将Smith&subject=Physics&room=Room
视为第一个字符串。因此subject
和room
将包含随机堆栈垃圾,这是您在第一个,
之后看到的内容。原因是scanf()
是一个非常简单的解析器;当它看到空白区域时,它开始寻找下一个字符串。由于您的输入不包含空格,因此它只使用URL参数列表的剩余部分作为第一个字符串。请参阅下文,了解更高级的格式。
要解析字符串,请查看strtok()
。使用strtok()
时,如果getenv()
返回字符串,则必须先复制,因为strtok()
修改字符串,并且您不允许修改{{1}返回的字符串1}}(可以阅读here)。
或者在字符串上循环搜索getenv()
。
但您也可以使用&
使用sscanf()
解析网址参数,如示例here所示。
另一方面,正确解析URL是很多工作,因为可能存在转换回适当字符的转义序列。因此,使用现有的库比自己编写代码更好。