使い方
#include <stdio.h> #include <stdlib.h> #include <string.h> // getの全文の最大サイズ ?aa=30&bb=40=&cc=100の場合は20となる #define MAX_GET_PARAMETER 255 // getのパラメタの名前の最大サイズ #define NAME_LENGTH_MAX 20 // getのパラメタの値の最大サイズ #define VALUE_LENGTH_MAX 80
を宣言しておき、
char data[MAX_GET_PARAMETER]="?aa=&bb=40&cc=100"; struct getdata *array; array = getGetData(data, array);
こうすると、arrayの中は、
array[0].szName = aaa array[0].szValue = array[1].szName = bb array[1].szValue = 40 array[2].szName = cc array[2].szValue = 100
こんな感じで格納される。
ソースコードは以下の通りだが、freeをどのタイミングでするかよくわからない。
// vim: set fdm=marker commentstring=;#%s: //↑vimで中括弧三つ分でテキストの折りたたみしたりするのに使用.vim以外な人は削除しましょう #include <stdio.h> #include <stdlib.h> #include <string.h> //#define /**{{{*/ // getの全文の最大サイズ ?aa=30&bb=40=&cc=100の場合は20となる #define MAX_GET_PARAMETER 255 // getのパラメタの名前の最大サイズ #define NAME_LENGTH_MAX 20 // getのパラメタの値の最大サイズ #define VALUE_LENGTH_MAX 80 /**}}}*/ //getの構造体 ?abc=35の場合 // szName 構造体の名前 abc // szValue 中身のデータ 35 // が入る. typedef struct getdata { /** {{{*/ char szName[NAME_LENGTH_MAX]; char szValue[VALUE_LENGTH_MAX]; } getdata; /**}}}*/ //プロトタイプ宣言 /** {{{*/ int getParametersNum(char* data); char* dispGetData( struct getdata* array ); struct getdata* getGetData(char* data, struct getdata* array); /**}}}*/ /** GET文の中の``=''の数を数え上げることで配列の要素数を求める * @param data getデータの全文 * @example data <- ``?aa=40&bb=30&cc=80'' * @return iRet =の数(要素数) */ int getParametersNum(char* data) { /** {{{ */ int iRet = 0; int i; for ( i = 0; data[i];i++ ) { if ( data[i] == '=' ) { iRet++; } } return iRet; } /** }}}*/ /**画面に格納されたパラメタと値を出力する. * @param array 格納されたデータ(構造体) */ char* dispGetData( struct getdata* array ) { /** {{{*/ int i; char* ret; sprintf(ret, ""); //配列に入っている要素を出力する for ( i = 0; strlen(array[i].szName) != 0; i++ ) { //fprintf(stdout, "array[%d].szName = %s\n", i, array[i].szName); //fprintf(stdout, "array[%d].szValue = %s\n", i, array[i].szValue); sprintf(ret, "%sarray[%d].szName = %s\n",ret, i, array[i].szName); sprintf(ret, "%sarray[%d].szValue = %s\n",ret, i, array[i].szValue); } //fprintf(stdout, "%s", ret); return ret; } /**}}}*/ struct getdata* getGetData(char* data, struct getdata* array) { /** {{{*/ char delimiter_amp[]="&"; char delimiter_equ[]="="; char *tok,*tokequ; char szBufName[NAME_LENGTH_MAX]; char szBufValue[VALUE_LENGTH_MAX]; char szTemp[MAX_GET_PARAMETER]; int iEqualNum = 0;//GET文の中の = の数. int i = 0; int j = 0; //fprintf(stdout, "I'm in getGetData. data = %s\n", data); //デリミタである=の数を数え上げる事で、要素の数を求める. iEqualNum = getParametersNum(data); //fprintf(stdout, "配列の数=%d\n", iEqualNum); //getの全文 //fprintf( stdout, "the data = %s\n", data); // get文の最初の文字は ? から始まるが、それは必要ないので削除する data[0] = data[1]; // メモリの確保(要素数は iEqualNumで取得することができている) array = (struct getdata*)malloc(sizeof(struct getdata) * iEqualNum ); if ( array == NULL ) { fprintf(stderr, "memory allocation error\n" ); exit(-1); } tok = strtok( data, delimiter_amp ); while (tok != NULL ) { // fprintf(stdout, "%d:%s\n",i, tok); // 今のtokは、実は [パラメタ]=[値]となっているので、さらにそれを=で分割する. strcpy(szTemp, tok); strcpy( array[i].szName, szTemp ); tok = strtok(NULL, delimiter_amp ); i++; } //とりあえず、構造体のszValueに入れたので、それを分割する. for ( i = 0; i < iEqualNum; i++ ) { j = 0; tokequ = strtok( array[i].szName, delimiter_equ ); while ( tokequ != NULL ) { //fprintf( stdout, "[%d]:[j=%d]%s\n", i,j, tokequ ); if ( j == 0 ) { //パラメタ名 strcpy( array[i].szName, tokequ ); } else if ( j == 1 ) { //値 strcpy( array[i].szValue, tokequ ); } tokequ = strtok(NULL, delimiter_equ ); j++; } } return array; } /**}}}*/ int main(int argc, char** argv) { char disp[1024]; char data[MAX_GET_PARAMETER]="?aa=&bb=40&cc=100&dd=24&ee=14&ff=2"; struct getdata *array; array = getGetData(data, array); //画面に格納出来たデータを出力する. //*disp = dispGetData(array); strcpy(disp, dispGetData(array)); fprintf(stdout, "%s", disp); free(array); return 0; }