C++ CGI中使用sscanf解析GET表单QUERY_STRING数据报错如何解决
CGI GET参数解析失败问题修复
存在的核心问题
- 野指针访问:
name和animal是未初始化的字符指针,没有分配内存空间,sscanf直接写入会触发内存访问错误
- 野指针访问:
- 参数名不匹配:前端下拉框的
name属性是animalList,但代码里sscanf匹配的参数名写为了animalName,完全对不上导致匹配失败
- 参数名不匹配:前端下拉框的
- 格式化字符串错误:
%s匹配规则是遇到空白字符才停止,会把QUERY_STRING里的&也读进第一个参数,需要用%[^&]表示匹配到&就停止,才符合URL参数的分隔规则
- 格式化字符串错误:
- 逻辑判断无效:
if (sscanf(...));后面多了一个分号,不管sscanf匹配是否成功,后续代码都会执行,判断逻辑完全失效
- 逻辑判断无效:
- 空指针未判断:
getenv("QUERY_STRING")有可能返回空指针,直接传给sscanf会触发崩溃,需要先做非空校验
- 空指针未判断:
修复后完整代码
#include <iostream> #include <string.h> #include <stdlib.h> #pragma warning(disable: 4996) using namespace std; int main() { cout << "Content-type:text/html\r\n\r\n"; cout << "<html>\n"; cout << "<head>\n"; cout << "<title>CGI 动物查询结果</title>\n"; cout << "</head>\n"; cout << "<body>\n"; char* data = getenv("QUERY_STRING"); // 先判断QUERY_STRING是否存在 if (data == NULL) { cout << "<p>未获取到请求参数</p>"; cout << "</body>"; return 1; } // 分配栈内存存储参数值,避免野指针 char name[256] = {0}; char animal[256] = {0}; // 修正参数名和格式化字符串,去掉多余分号 if (sscanf(data, "nameEntered=%[^&]&animalList=%s", name, animal) == 2) { // 按预期格式输出 cout << "name=\"" << name << "\"<br><br>"; cout << "animal=\"" << animal << "\""; } else { cout << "<p>参数解析失败</p>"; } cout << "</body>"; return 0; }
补充说明
如果用户输入的姓名包含中文、空格或者特殊字符,还需要额外对QUERY_STRING做URL解码处理,上述代码仅针对ASCII字符的常规场景生效。
内容的提问来源于stack exchange,提问作者Peter Holmes
相关产品推荐
相关产品推荐

