【问题】用c编写cgi程序如何取出html表单post来的数据?
【分析】html表单post来的数据形如username="zhang"&&password="123456"&&useid="012"
【方法1】
#include <stdio.h> #include <stdlib.h> #include <string.h> char* getcgidata(FILE* fp, char* requestmethod); int main() { char *input; char *req_method; char name[64]; char pass[64]; char userid[64]; int i = 0; int j = 0; // printf("Content-type: text/plain; charset=iso-8859-1\n\n"); printf("Content-type: text/html\n\n"); printf("The following is query reuslt:<br><br>"); req_method = getenv("REQUEST_METHOD"); input = getcgidata(stdin, req_method); for ( i = 9; i < (int)strlen(input); i++ ) { if ( input[i] == '&' ) { name[j] = '\0'; break; } name[j++] = input[i]; } for ( i = 19 + strlen(name), j = 0; i < (int)strlen(input); i++ ) { if ( input[i] == '&' ) { pass[j] = '\0'; break; } pass[j++] = input[i]; } for ( i = 30 + strlen(pass)+ strlen(name), j = 0; i < (int)strlen(input); i++ ) { userid[j++] = input[i]; } userid[j] = '\0'; printf("Your Username is %s<br>Your Password is %s<br>Your userid is %s<br> \n", name, pass,userid); return 0; } char* getcgidata(FILE* fp, char* requestmethod) { char* input; int len; int size = 1024; int i = 0; if (!strcmp(requestmethod, "GET")) { input = getenv("QUERY_STRING"); return input; } else if (!strcmp(requestmethod, "POST")) { len = atoi(getenv("CONTENT_LENGTH")); input = (char*)malloc(sizeof(char)*(size + 1)); if (len == 0) { input[0] = '\0'; return input; } while(1) { input[i] = (char)fgetc(fp); if (i == size) { input[i+1] = '\0'; return input; } --len; if (feof(fp) || (!(len))) { i++; input[i] = '\0'; return input; } i++; } } return NULL; }
【方法2】
1 先将post来的数据整体读入info
char *info=NULL; char username[64]; char passwd[64]; int userid; int lenstr=0; memset(username,0,64); memset(passwd,0,64); userid=0; /* * Get the data by post method from index.html */ lenstr=atoi(getenv("CONTENT_LENGTH")); info=(char *)malloc(lenstr+1); fread(info,1,lenstr,stdin);
2 将info作为文件流输入,利用sscanf提取子串
sscanf(info,"username=%[^&]&passwd=%[^&]&userid=%d",username,passwd,&userid); free(info);
注:如果数据为实型,则利用sscanf时,要加上&,如上例userid
【思考】如果子串为username=zhang; passwd=123; userid=012,如何用【方法2】提取?
sscanf(info,"username=%[^;]; passwd=%[^;]; userid=%d",&username,&passwd,&userid);
注意:将%[^&]&替换为%[^;];。通过本例,可以明白%[^;];的用法。
【解析】%[^&]是正则表达式,详细请参考:
http://blog.chinaunix.net/space.php?uid=9195812&do=blog&cuid=499274