CGI処理をするときに、受信したデータはURLエスケープされています。


「%93%E0%8A%74」みたいになっていますよね!


これを元に戻してみましょう。



【サンプル】

#include <cstdlib>
#include <iostream>
#include <map>
#include <string>
#include <sstream>

#include "boost/tokenizer.hpp"
#include "boost/progress.hpp"


using namespace std;
using namespace boost;


    

/**
isからget()した値をURLアンエスケープし、1バイト分の文字を返す。
@return !is.fail() を返す
*/

const bool getChar(istream& is, char& c)
{
    //
    is.get(c);


    //エスケープ文字ではない場合(空白)
    if(c == '+'){
        c = ' ';
    }else if(c == '%'){
        char tmp[3];
        char* endstr;


        //エスケープ文字を元に戻す
        is.get(tmp, 3);
        c = (char)strtol(tmp, &endstr, 16);
    }


    return !is.fail();
};



/**
dataをデコードして返す。
@return デコード結果を返す。失敗の場合""
*/

const string unescapeURL(const string& data)
{
    istringstream iss(data);
    ostringstream ret;
    char c;


    while(getChar(iss, c)){
        if(c == '\0'){
            //エラーの場合
            return "";
        }else if(c == '\r'){
            //改行(\r\n or \r)の場合、\nに変換
            getChar(iss, c);
            if(c != '\n') ret << "\n";
        }


        //1バイト追加
        ret << c;
    }

    return ret.str();
};


/**
paramsに、キー⇒パラメタ名、値⇒データ、を追加する。
*/

void createWebParam(map<string, string>& params, const string& paramString)
{
    typedef tokenizer<char_separator<char> > ParamToken;
    typedef ParamToken::iterator ParamIterator;


    //&で区切る token
    char_separator<char> sep("&");
    ParamToken token(paramString, sep);
    ParamIterator i = token.begin();
    ParamIterator end = token.end();


    //マップにパラメタを代入していく
    for(; i!=end; ++i){
        string tmp = *i;
        string::size_type n = tmp.find('=');
        string name = unescapeURL(tmp.substr(0, n));


        //パラメタ名とデータを分解して代入
        if(n != string::npos){
            string data = tmp.substr(n+1);
            params[name] = unescapeURL(data);
        }else{
            params[name] = "";
        }
    }
};



int main(int argc, char *argv[])
{
    typedef map<string, string> ParamMap;


    //パラメタの分解
    ParamMap params;
    createWebParam(params,

        "daijin=+%93%E0%8A%74super%91%8D%97%9D%91%E5%90%62&lang=ja&ct=clnk&cd=1&key=B");
    
    //作成されたパラメタを出力する
    ParamMap::iterator i = params.begin();
    ParamMap::iterator end = params.end();
    for(; i != end; ++i){
        cout << i->first << "=" << i->second << endl;
    }
    
    system("PAUSE");
    return EXIT_SUCCESS;
}



【出力】

cd=1
ct=clnk
daijin= 内閣super総理大臣
key=B
lang=ja
続行するには何かキーを押してください . . .



【説明】

URLのアンエスケープは、それほど難しくありません。


+ ・・・半角空白に変換します

%XX ・・・16進数の文字列として、数字に変換します。

その他・・・そのまま文字として何も変換しません。



上記をプログラムにしたのがサンプルです。

もっとシンプルな方法があるかもしれませんので色々試してみると面白いかも(^^)




参考:

・GETやPOSTのデータを取得するには?

・windowsでWEBをするには?

・HTTP通信とは?

・クッキーとは?