2010-06-04 70 views
6

我是新來的C++和cgicc,我想知道是否有一種簡單的方法來解析CGI腳本的get參數? ?action=yes&function=no成一個數組或類似的東西?cgicc查詢字符串解析

+0

這與你的問題完全無關,但我剛剛注意到你的名字是TheOnly92,在這個時刻你的聲望恰好在92!嘿。讓我微笑。 – 2010-06-04 07:45:44

回答

0

我設計C++中的程序,它可以幫助你

// (c) 2011 enthusiasticgeek 
// The code is adapted from James Marshall's getcgivars.c 
// tested with the following webservers 
// This code is distributed in the hope that it will be useful, 
// but WITHOUT ANY WARRANTY; without even the implied warranty of 
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
// Mongoose and LIGHTTPD 
// Feel Free to use leave credits intact 

// Compile: 
// g++ -g testparse.cpp -o testparse.cgi 
// To run: 
// place cgi file in the appropriate directory depending on server configuration 
// Start webserver and then open internet browser and (assuming script running on localserver, port 8080 under 'cgi_bin' directory) enter something similar to 
// http://localhost:8080/cgi_bin/testparse.cgi?name1=value1&name2=value2&name3=value3 

#include <iostream> 
#include <string> 
#include <vector> 
#include <algorithm> 
#include <iterator> 
#include <sstream> 
#include <cstdio> 
#include <map> 
#include <stdlib.h> 
#include <cstring> 
#include <cctype> 
#include <ctype.h> 

using namespace std; 

vector<string> split(const string& s, const string& delim, const bool keep_empty = true) 
{ 
    vector<string> result; 
    if (delim.empty()) { 
    result.push_back(s); 
    return result; 
    } 
    string::const_iterator substart = s.begin(), subend; 
    while (true) { 
    subend = search(substart, s.end(), delim.begin(), delim.end()); 
    string temp(substart, subend); 
    if (keep_empty || !temp.empty()) { 
     result.push_back(temp); 
    } 
    if (subend == s.end()) { 
     break; 
    } 
    substart = subend + delim.size(); 
    } 
    return result; 
} 


std::map<std::string, std::string>& map_pairs(char* character, std::map<std::string, std::string>& Elements) 
{ 
string test; 
string key; 
string value; 
vector<string>::iterator it; 
string character_string = character; 
vector<string> words; 


//Elements.insert(std::pair<string,string>("0","0")); 
    //cout << "########## SPLITTING STRING INTO SMALLER CHUNKS ################## " << endl; 
    words = split(character_string, "&"); 
    //cout << "########## GENERATING KEY VALUE PAIRS ################## " << endl; 
    for (it=words.begin(); it!=words.end(); ++it) 
    {  
    test = *it; 
    cout<< "string:" << test << endl; 

    const string::size_type pos_eq = test.find ('=');  
    if (pos_eq != string::npos) 
    { 
    //Assign Key and Value Respectively 
    key = test.substr (0, pos_eq); 
    value = test.substr (pos_eq + 1); 
    //cout << "key = " << key << " and value = " << value << endl; 
    Elements.insert(std::pair<string,string>(key,value)); 
    } 

    } 


return Elements; 
} 

std::map<std::string, std::string>& getcgivars(std::map<std::string, std::string>& Elements) 
{ 
    register int i ; 
    char *request_method = NULL; 
    int content_length; 
    char *cgiinput = NULL; 

    // Depending on the request method, read all CGI input into cgiinput 
    // (really should produce HTML error messages, instead of exit()ing) 
    request_method= getenv("REQUEST_METHOD") ; 
    if (!strcmp(request_method, "GET") || !strcmp(request_method, "HEAD")) { 
    // Some servers apparently don't provide QUERY_STRING if it's empty, 
    // so avoid strdup()'ing a NULL pointer here.      
    char *qs ; 
    qs= getenv("QUERY_STRING") ; 
    cgiinput= strdup(qs ? qs : "") ; 
    } 
    else if (!strcmp(request_method, "POST")) { 
    // strcasecmp() is not supported in Windows-- use strcmpi() instead 
    if (strcasecmp(getenv("CONTENT_TYPE"), "application/x-www-form-urlencoded")) { 
     printf("getcgivars(): Unsupported Content-Type.\n") ; 
     exit(1) ; 
    } 
    if (!(content_length = atoi(getenv("CONTENT_LENGTH")))) { 
     printf("getcgivars(): No Content-Length was sent with the POST request.\n") ; 
     exit(1) ; 
    } 
    if (!(cgiinput = new char[content_length+1])) { 
     printf("getcgivars(): Could not \"new\" for cgiinput.\n") ; 
     exit(1) ; 
    } 
    if (!fread(cgiinput, content_length, 1, stdin)) { 
     printf("Couldn't read CGI input from STDIN.\n") ; 
     exit(1) ; 
    } 
    cgiinput[content_length]='\0' ; 
    } 
    else { 
    printf("getcgivars(): unsupported REQUEST_METHOD\n") ; 
    exit(1) ; 
    } 

    map_pairs(cgiinput,Elements); 

    return Elements; 
} 

int main(int argc, char *argv[]) 
{ 
    int i ;   
    std::map<std::string, std::string> Elements; 
    getcgivars(Elements); 
    // Print the CGI response header, required for all HTML output. 
    // Note the extra \n, to send the blank line.     
    printf("Content-type: text/html\n\n") ; 

    // HTML response page.   
    printf("<html>\n") ; 
    printf("<head><title>CGI Results</title></head>\n") ; 
    printf("<body>\n") ; 
    printf("<center><h1>CGI FORM TEST</h1></center>\n") ; 
    printf("<center>HTML form sent the following variables\n"); 
    printf("to the testparse.cgi program:</center>\n") ; 
    printf("<ul>\n") ; 

    // Print the CGI variables sent by the user. Note the list of 
    // variables alternates names and values, and ends in NULL. 
    for(map<string,string>::iterator ii=Elements.begin(); ii!=Elements.end(); ++ii) 
    { 
     cout << "<li>" << (*ii).first << "=" << (*ii).second;    
    } 

    printf("</ul>\n") ; 
    printf("<p>This data is available to you in testparse.cpp<br>\n"); 
    printf("as the contents of \"key\" and \"value\"\n"); 
    printf("</body>\n") ; 
    printf("</html>\n") ; 

    Elements.clear(); 

    return 0; 
} 
10

下面是一個使用包含在C中的正則表達式庫的簡單函數++ 11。

#include <regex> 

// ... 

std::map<std::string, std::string> Foo::Parse(const std::string& query) 
{ 
    std::map<std::string, std::string> data; 
    std::regex pattern("([\\w+%]+)=([^&]*)"); 
    auto words_begin = std::sregex_iterator(query.begin(), query.end(), pattern); 
    auto words_end = std::sregex_iterator(); 

    for (std::sregex_iterator i = words_begin; i != words_end; i++) 
    { 
     std::string key = (*i)[1].str(); 
     std::string value = (*i)[2].str(); 
     data[key] = value; 
    } 

    return data; 
} 
+0

這一切都很好,但截至2014年初,libstdC++支持正則表達式基本上不存在。 – 2014-02-27 15:32:09