CGI环境下C++括号平衡校验程序始终返回Valid问题排查
解决CGI环境下括号平衡检查总是返回"Valid"的问题
嘿,这问题我太熟了!你这是踩了CGI POST数据处理的坑,再加上表单里的一个小失误,才导致不管输入啥都返回"Valid"。咱们一步步拆解:
核心问题1:POST数据的读取方式完全错误
在repl.it里你直接输入字符串,cin>>expression能正常拿到内容,但CGI环境下用POST提交表单时,标准输入里的不是纯字符串,而是URL编码的键值对数据(比如parentheses=%28%5B%7B%7D%5D%29这种格式)。你现在用cin>>expression,只会读取到第一个分隔符(比如=)之前的内容,最后expression是空字符串。而你的balanced函数对空字符串会返回true(栈本来就是空的),所以永远显示"Valid"。
核心问题2:表单输入框的name多了个空格
看你的HTML代码:<input type="text" name="parentheses "/>,这里name的末尾多了个空格!就算你正确处理POST数据,也会因为键名不匹配(找parentheses但实际是parentheses ),拿不到用户输入的值,最后还是处理空字符串。
具体修复步骤
第一步:修正HTML表单的name
把输入框的name里的空格去掉:
<input type="text" name="parentheses"/>
第二步:修改main.cpp来正确处理POST数据
需要读取POST的完整数据,解析出parentheses对应的用户输入,还要处理URL编码(浏览器会把特殊字符转成编码格式,比如(变成%28)。修改后的main.cpp如下:
#include <iostream> #include <string> #include <cstdlib> #include <cctype> #include "stacksLab.h" using namespace std; // 解析POST键值对,获取指定key的解码后的值 string getPostValue(const string& postData, const string& key) { size_t keyPos = postData.find(key + "="); if (keyPos == string::npos) return ""; // 定位到值的起始位置 size_t valStart = keyPos + key.length() + 1; size_t valEnd = postData.find("&", valStart); if (valEnd == string::npos) valEnd = postData.length(); // 解码URL编码 string decodedVal; for (size_t i = valStart; i < valEnd; ++i) { if (postData[i] == '%' && i + 2 < valEnd) { // 处理%XX格式的编码 char hex1 = postData[i+1]; char hex2 = postData[i+2]; char decodedChar = ((isdigit(hex1) ? hex1 - '0' : toupper(hex1) - 'A' + 10) * 16) + ((isdigit(hex2) ? hex2 - '0' : toupper(hex2) - 'A' + 10)); decodedVal += decodedChar; i += 2; } else if (postData[i] == '+') { // 处理空格的+编码 decodedVal += ' '; } else { decodedVal += postData[i]; } } return decodedVal; } int main() { cout << "Content-type: text/html\n\n"; Stacks st; string expression; // 读取POST数据 char* contentLenStr = getenv("CONTENT_LENGTH"); if (contentLenStr != nullptr) { int contentLen = atoi(contentLenStr); if (contentLen > 0) { char* postBuffer = new char[contentLen + 1]; cin.read(postBuffer, contentLen); postBuffer[contentLen] = '\0'; // 解析出用户输入的括号表达式 expression = getPostValue(string(postBuffer), "parentheses"); delete[] postBuffer; } } if (st.balanced(expression)) { cout << "Valid\n"; } else { cout << "Not Valid\n"; } return 0; }
修复后的逻辑说明
- 通过
getenv("CONTENT_LENGTH")获取POST数据的总长度,确保能完整读取所有数据; - 用
cin.read()读取整个POST内容,避免cin>>截断数据的问题; getPostValue函数负责解析键值对,并把URL编码的字符转成原始字符(比如%28转回();- 修正表单name后,能准确匹配到用户输入的括号字符串。
这样修改后,CGI环境下就能正常处理用户输入的括号,返回正确的"Valid"或"Not Valid"了!
内容的提问来源于stack exchange,提问作者Cheryl
相关产品推荐
相关产品推荐

