隨筆-40  評(píng)論-66  文章-0  trackbacks-0
          我們來看看到底如何從POST表單收集數(shù)據(jù)到CGI程序,下面給出了一個(gè)比較簡(jiǎn)單的C源代碼:     
              
           

           

          #include<stdio.h>
          #include<stdlib.h>    
          #define MAXLEN 80    
          #define EXTRA 5
          /*   4個(gè)字節(jié)留給字段的名字"data",   1個(gè)字節(jié)留給"="   */
          #define   MAXINPUT   MAXLEN+EXTRA+2 
          /*   1個(gè)字節(jié)留給換行符,還有一個(gè)留給后面的NULL   */
          #define DATAFILE "../data/data.txt"
          /*   要被添加數(shù)據(jù)的文件   */

          void   unencode(char   *src,   char   *last,   char   *dest)
          {
           for(; src != last; src++, dest++)
            if(*src == "+")
             *dest = " ";
            else if(*src == "%") {    
             int   code;    
             if(sscanf(src+1,"%2x",&code)!=1)code="?";
             *dest=code;
             src   +=2;}
            else
             *dest=*src;
            *dest=" ";
            *++dest="";    
          }    

          int   main(void)    
          {    
           char *lenstr;
           char input[MAXINPUT], data[MAXINPUT];
           long len;
           
           printf("%s%c%c", "Content-Type:text/html;charset=gb2312",13,10);
           printf("<TITLE>Response</TITLE>");

           lenstr=getenv("CONTENT_LENGTH");
           if(lenstr==NULL || sscanf(lenstr,"%ld",&len)!=1 || len>MAXLEN)
            printf("<P>表單提交錯(cuò)誤");
           else{
            FILE *f;
            fgets(input,   len+1,   stdin);
            unencode(input+EXTRA,   input+len,   data);

            f =fopen(DATAFILE, "a");
            if(f == NULL)    
             printf("<P>對(duì)不起,意外錯(cuò)誤,不能夠保存你的數(shù)據(jù)");    
            else
             fputs(data,   f);    
            fclose(f);
            printf("<P>非常感謝,您的數(shù)據(jù)已經(jīng)被保存<BR>%s",data);    
           }    
           return   0;    
          }    

              
                 從本質(zhì)上來看,程序先從CONTENT_LENGTH環(huán)境變量中得到數(shù)據(jù)的字長(zhǎng),然后讀取相應(yīng)長(zhǎng)度的字符串。因?yàn)閿?shù)據(jù)內(nèi)容在傳輸?shù)倪^程中是經(jīng)過了編碼的,所以必須進(jìn)行相應(yīng)的解碼。編碼的規(guī)則很簡(jiǎn)單,主要的有這幾條:     

          1.   表單中每個(gè)每個(gè)字段用字段名后跟等號(hào),再接上上這個(gè)字段的值來表示,每個(gè)字段之間的內(nèi)容用&連結(jié);    2.   所有的空格符號(hào)用加號(hào)代替,所以在編碼碼段中出現(xiàn)空格是非法的;    
          3.   特殊的字符比如標(biāo)點(diǎn)符號(hào),和一些有特定意義的字符如“+”,用百分號(hào)后跟其對(duì)應(yīng)的ACSII碼值來表示。    

          例如:如果用戶輸入的是:     
             
          Hello   there!    

          那么數(shù)據(jù)傳送到服務(wù)器的時(shí)候經(jīng)過編碼,就變成了data=Hello+there%21   上面的unencode()函數(shù)就是用來把編碼后的數(shù)據(jù)進(jìn)行解碼的。在解碼完成后,數(shù)據(jù)被添加到data.txt文件的尾部,并在瀏覽其中回顯出來。    

          把文件編譯完成后,把它改名為collect.cgi后放在CGI目錄中就可以被表單調(diào)用了。下面給出了其相應(yīng)的表單:    

          <FORM   ACTION="/cgi-bin/collect.cgi"   METHOD="POST"   >
          <P>請(qǐng)輸入您的留言(最多80個(gè)字符):<BR>
          <INPUT   NAME="data"   SIZE="60"   MAXLENGTH="80"   ><BR>
          <INPUT   TYPE="SUBMIT"   VALUE="確定">
          </FORM   >    
             
             
                 事實(shí)上,這個(gè)程序只能作為例子,是不能夠正式的使用的。它漏掉了很關(guān)鍵的一個(gè)問題:當(dāng)有多個(gè)用戶同時(shí)像文件寫入數(shù)據(jù)是,肯定會(huì)有錯(cuò)誤發(fā)生。而對(duì)于一個(gè)這樣的程序而言,文件被同時(shí)寫入的幾率是很大的。因此,在比較正式的留言版程序中,都需要做一些更多的考慮,比如加入一個(gè)信號(hào)量,或者是借助于一個(gè)鑰匙文件等。因?yàn)槟侵皇蔷幊痰募记蓡栴},在這兒就不多說了。

          posted on 2008-02-27 13:52 Super·shen BLOG 閱讀(2776) 評(píng)論(1)  編輯  收藏

          評(píng)論:
          # re: C語言CGI程序 POST表單處理 2008-06-06 19:23 | fdsafd

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 五原县| 松溪县| 临洮县| 黄浦区| 平陆县| 南昌县| 菏泽市| 买车| 舞钢市| 永康市| 盐边县| 慈利县| 阿拉善右旗| 黑水县| 类乌齐县| 葫芦岛市| 鹤壁市| 治县。| 凭祥市| 钟山县| 临澧县| 永康市| 夏河县| 腾冲县| 大悟县| 临邑县| 朔州市| 顺义区| 蒙山县| 拉萨市| 仁化县| 东乌珠穆沁旗| 响水县| 日喀则市| 垦利县| 简阳市| 昌黎县| 汶上县| 钦州市| 垫江县| 平乡县|