0

我在下面有以下 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;
}

每当我单击提交按钮时,它都会输出

(null),Ã…,œí

我的代码有什么问题?谢谢!

已编辑:代码已编辑,但输出:

Smith&subject=物理&room=Room,Xøm·l,

4

1 回答 1

0

您最初没有为teachersubject和分配内存room。您使用固定大小的块进行了更正;当您 100% 确定您的字符串永远不会变长(在奇怪的错误情况下也是如此)时,这是一个解决方案。

您不需要为data.

Achar*只不过是一个指向字符串的指针;它没有任何实际chars 的存储空间。

你可以做:

...
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第一个字符串。所以subjectandroom将包含随机堆栈垃圾,这就是您在第一个,. 原因是这scanf()是一个非常简单的解析器;当它看到空白时,它开始寻找下一个字符串。由于您的输入不包含空格,因此它只是将 URL 参数列表的整个剩余部分作为第一个字符串。请参阅下面的更高级的格式。

要解析您的字符串,请查看strtok(). 使用时strtok(),如果返回的字符串必须先进行复制getenv(),因为strtok()修改了字符串,并且不允许修改返回的字符串getenv()(可以阅读here)。

或在字符串上进行 while 循环以搜索&.

但您也可以使用sscanf()with解析 URL 参数,如此[^&]示例所示。

另一方面,正确解析 URL 需要做很多工作,因为您可能需要将转义序列转换回相应的字符。因此,最好使用现有的库而不是自己编写代码。

于 2013-08-18T09:29:59.607 回答