読者です 読者をやめる 読者になる 読者になる

使い方

#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;
}