posts - 108,comments - 56,trackbacks - 0
               ☆去掉首尾空格的函數(shù)
            char * trim(char * s)   
            {
              if(s==NULL)   
                  return NULL;
              unsigned len=strlen(s);   
              register char *p1=s;   
              register char *p2=s+len-1;   
              while(*p1==' ')
                 p1++;   
              if(p1>=p2){
                   memcpy(s,p1,strlen(p1)+1);
                   return s;
              }
              while(*p2==' ')
                 p2--;   
              memcpy(s,p1,p2-p1+1);   
              *(s+(p2-p1)+1)=0;   
              return(s);   
            }  


               ☆比較內(nèi)存內(nèi)容memcmp
          表頭文件:#include <string.h>
          定義函數(shù):
          int memcmp(const void *s1, const void *s2, size_t n)
          函數(shù)說(shuō)明:memcmp()用來(lái)比較s1和s2所指的內(nèi)存區(qū)間前n個(gè)字符。字符串大小的比較是以ASCII碼表上的順序來(lái)決定,此順序亦為字符的值。memcmp()首先將s1第一個(gè)字符值減去s2第一個(gè)字符值,若差值為0則再繼續(xù)比較下個(gè)字符,若差值不為0則將差值返回。

          返回值:若參數(shù)s1和s2所指定的內(nèi)存內(nèi)容都完全相同則返回0值。s1若大于s2則返回大于0的值。s1若小于s2則返回小于0的值
          范例:
          #include  
          <string.h>
          main()
          {
              
          char  *a="aBcDeF";
              
          char  *b="AbCdEf";
              printf(
          "%d", memcmp((void *) a, (void *) b, 6)); 
          }


               ☆sprintf()函數(shù)
             sprintf跟printf在用法上差不多,只是打印的目的地不同,前者打印到字符串中,后者直接在命令行上輸出。
             定義函數(shù):
          int sprintf( char *buffer, const char *format [,argument]  );
             經(jīng)典用途:格式化數(shù)字字符串;連接字符串(可以連接多個(gè),比strcat強(qiáng))。
             注意:小心第一個(gè)參數(shù)的長(zhǎng)度不夠。為了安全,可以使用
          %.ns來(lái)控制輸出參數(shù)的最多個(gè)數(shù)。而且好像buffer不是申明為字符數(shù)組會(huì)報(bào)錯(cuò)。
             范例:
             #include <stdio.h>
            int main(void){
               char * a="abcdefg";
               char b[15];
               sprintf(b,"%.7s",a);
               printf("result=%s\n",b);
            }


               ☆比較字符串函數(shù)
          1)strncmp
            表頭文件
          <string.h>
            定義函數(shù)
          int strncmp(char *str1, char *str2, int maxlen); 
            和memcmp類似
          2)strncasecmp(不區(qū)分大小寫)
             定義函數(shù)
          int strncasecmp(char *str1, char *str2, int maxlen); 
          3) memcmp()函數(shù)與strncmp()函數(shù)基本相似,只是它在遇到NUL字符時(shí)不會(huì)結(jié)束。


               ☆atexit
             注冊(cè)一個(gè)給定的函數(shù),該函數(shù)在程序exit時(shí)候被調(diào)用。(不管是通過(guò)exit(3)或者還是通過(guò)從程序的main函數(shù)中返回)。 注冊(cè)的函數(shù)是反序被調(diào)用的;沒(méi)有參數(shù)。至少32個(gè)函數(shù)總是可以被注冊(cè)的,只要有充分的分配的內(nèi)存,更多的函數(shù)也是允許的。
             定義函數(shù)
          int atexit(void (*function)(void)) 
             表頭文件:stdlib.h
             例子
          #include 
          <stdlib.h>
          int atexit(void (*function)(void));
          #include 
          <stdio.h>
          void fn(void );
          int main( void )
          {
           atexit( fn);
           printf( 
          "main\n" );
          }
          void fn()
          {
           printf( 
          "fn\n" );
          }


               ☆segmentation fault
             如果在運(yùn)行的時(shí)候,非法訪問(wèn)內(nèi)存就會(huì)出現(xiàn)"segmentation fault"的結(jié)果。
             例如:
             
          int i=100;
             printf(
          "%s",i);
             這樣會(huì)直接取訪問(wèn)100地址的空間。


               ☆malloc動(dòng)態(tài)分配內(nèi)存
             例如分配100個(gè)字符空間:char * p=(char *)malloc(100*sizeof(char));
             釋放空間:free(p);
             注意
             
          1)申請(qǐng)了內(nèi)存空間后,必須檢查是否分配成功。如果分配失敗得到的p是NULL;
             
          2)當(dāng)不需要再使用時(shí),記得釋放(和java就是不一樣),如果不釋放會(huì)造成內(nèi)存泄漏;釋放后應(yīng)該把指向這塊內(nèi)存的指針指向NULL,防止程序后面不小心使用了它。
              
          3)如果釋放兩次及兩次以上會(huì)出現(xiàn)錯(cuò)誤(釋放空指針例外,釋放空指針其實(shí)也等于啥也沒(méi)做,所以釋放空指針釋放多少次都沒(méi)有問(wèn)題)。
              
          4)malloc()函數(shù)的類型是(void *),任何類型的指針都可以轉(zhuǎn)換成(void *),但是最好還是在前面進(jìn)行強(qiáng)制類型轉(zhuǎn)換,因?yàn)檫@樣可以躲過(guò)一些編譯器的檢查。

              malloc從哪里得到空間:
              從堆里面獲得空間。也就是說(shuō)函數(shù)返回的指針是指向堆里面的一塊內(nèi)存。操作系統(tǒng)中有一個(gè)記錄空閑內(nèi)存地址的鏈表。當(dāng)操作系統(tǒng)收到程序的申請(qǐng)時(shí),就會(huì)遍歷該鏈表,然后就尋找第一個(gè)空間大于所申請(qǐng)空間的堆結(jié)點(diǎn),然后就將該結(jié)點(diǎn)從空閑結(jié)點(diǎn)鏈表中刪除,并將該結(jié)點(diǎn)的空間分配給程序。


               ☆堆/棧
              是大家共有的空間,分全局堆和局部堆。全局堆就是所有沒(méi)有分配的空間,局部堆就是用戶分配的空間。堆在操作系統(tǒng)對(duì)進(jìn)程初始化的時(shí)候分配,運(yùn)行過(guò)程中也可以向系統(tǒng)要額外的堆。
              是線程獨(dú)有的,保存其運(yùn)行狀態(tài)和局部自動(dòng)變量的。棧在線程開(kāi)始的時(shí)候初始化,每個(gè)線程的棧互相獨(dú)立。每個(gè)函數(shù)都有自己的棧,棧被用來(lái)在函數(shù)之間傳遞參數(shù)。操作系統(tǒng)在切換線程的時(shí)候會(huì)自動(dòng)的切換棧,就是切換SS
          /ESP寄存器。棧空間不需要在高級(jí)語(yǔ)言里面顯式的分配和釋放。


               ☆字符數(shù)據(jù)賦值
            char str[5]="1234";  
            str
          ="abcd";//這樣會(huì)出錯(cuò)(將常量字符串的地址付給一個(gè)字符指針)


               ☆分解字符串(類似JAVA中的split)
            定義函數(shù)extern char *strtok(char *s, char *delim);     
            表頭文件
          <string.h>
            功能:分解字符串為一組標(biāo)記串。s為要分解的字符串,delim為分隔符字符串。
            說(shuō)明:首次調(diào)用時(shí),s必須指向要分解的字符串,隨后調(diào)用要把s設(shè)成NULL。strtok在s中查找包含在delim中的字符并用NULL(
          '\0')來(lái)替換,直到找遍整個(gè)字符串。返回指向下一個(gè)標(biāo)記串。當(dāng)沒(méi)有標(biāo)記串時(shí)則返回空字符NULL。  
            舉例(怪怪的):
                 #include 
          <string.h>
                #include 
          <stdio.h>
                
          int main(void)
                {
                  
          char s[]="a,b,c,d";
                  
          char *p;
                  p
          =strtok(s,",");
                  
          while(p!=NULL)
                  {
                    printf(
          "%s\n",p);
                    p=strtok(NULL,
          ",");
                  }
                  
          return 0;
                }


               ☆求字符串長(zhǎng)度的函數(shù)strlen
            定義函數(shù):size_t strlen(const char * s);
            表頭文件:
          <string.h>
            函數(shù)功能:計(jì)算字符串s的長(zhǎng)度,不包括
          '\0';
            舉例:
            
          int main(void){
                char a[5]="abc";
                printf("%d",strlen(a));
           }


               ☆正則表達(dá)式
            標(biāo)準(zhǔn)的C不支持正則表達(dá)式,但有一些函數(shù)庫(kù)可以輔助完成這一功能,其中最著名的當(dāng)數(shù)Philip Hazel的Perl-Compatible Regular Expression庫(kù),許多Linux發(fā)行版本都帶有這個(gè)函數(shù)庫(kù)。
            使用正則表達(dá)式用三個(gè)過(guò)程:編譯正則表達(dá)式
          ->匹配正則表達(dá)式->釋放正則表達(dá)式

            
          1)編譯正則表達(dá)式
            為了提高效率,在將一個(gè)字符串與正則表達(dá)式進(jìn)行比較之前,首先要用regcomp()函數(shù)對(duì)它進(jìn)行編譯,將其轉(zhuǎn)化為regex_t結(jié)構(gòu):
            
          int regcomp(regex_t *preg, const char *regex,int cflags);
            參數(shù)regex是一個(gè)字符串,它代表將要被編譯的正則表達(dá)式;參數(shù)preg指向一個(gè)聲明為regex_t的數(shù)據(jù)結(jié)構(gòu),用來(lái)保存編譯結(jié)果;參數(shù)cflags決定了正則表達(dá)式該如何被處理的細(xì)節(jié)。如果函數(shù)regcomp()執(zhí)行成功,并且編譯結(jié)果被正確填充到preg中后,函數(shù)將返回0,任何其它的返回結(jié)果都代表有某種錯(cuò)誤產(chǎn)生。 

            
          2)匹配正則表達(dá)式 
            一旦用regcomp()函數(shù)成功地編譯了正則表達(dá)式,接下來(lái)就可以調(diào)用regexec()函數(shù)完成模式匹配: 
            
          int regexec(const regex_t *preg, const char *string, size_t nmatch,regmatch_t pmatch[], int eflags); 
            typedef struct {regoff_t rm_so; regoff_t rm_eo; } regmatch_t;
            參數(shù)preg指向編譯后的正則表達(dá)式,參數(shù)string是將要進(jìn)行匹配的字符串,而參數(shù)nmatch和pmatch則用于把匹配結(jié)果返回給調(diào)用程序,最后一個(gè)參數(shù)eflags決定了匹配的細(xì)節(jié)。 
            在調(diào)用函數(shù)regexec()進(jìn)行模式匹配的過(guò)程中,可能在字符串string中會(huì)有多處與給定的正則表達(dá)式相匹配,參數(shù)pmatch就是用來(lái)保存這些匹配位置的,而參數(shù)nmatch則告訴函數(shù)regexec()最多可以把多少個(gè)匹配結(jié)果填充到pmatch數(shù)組中。當(dāng)regexec()函數(shù)成功返回時(shí),從string
          +pmatch[0].rm_so到string+pmatch[0].rm_eo是第一個(gè)匹配的字符串,而從string+pmatch[1].rm_so到string+pmatch[1].rm_eo,則是第二個(gè)匹配的字符串,依此類推。 

            
          3)釋放正則表達(dá)式 
            無(wú)論什么時(shí)候,當(dāng)不再需要已經(jīng)編譯過(guò)的正則表達(dá)式時(shí),都應(yīng)該調(diào)用函數(shù)regfree()將其釋放,以免產(chǎn)生內(nèi)存泄漏。 
            
          void regfree(regex_t *preg);
            函數(shù)regfree()不會(huì)返回任何結(jié)果,它僅接收一個(gè)指向regex_t數(shù)據(jù)類型的指針,這是之前調(diào)用regcomp()函數(shù)所得到的編譯結(jié)果。 
            如果在程序中針對(duì)同一個(gè)regex_t結(jié)構(gòu)調(diào)用了多次regcomp()函數(shù),POSIX標(biāo)準(zhǔn)并沒(méi)有規(guī)定是否每次都必須調(diào)用regfree()函數(shù)進(jìn)行釋放,但建議每次調(diào)用regcomp()函數(shù)對(duì)正則表達(dá)式進(jìn)行編譯后都調(diào)用一次regfree()函數(shù),以盡早釋放占用的存儲(chǔ)空間。 

            
          4)報(bào)告錯(cuò)誤信息 
            如果調(diào)用函數(shù)regcomp()或regexec()得到的是一個(gè)非0的返回值,則表明在對(duì)正則表達(dá)式的處理過(guò)程中出現(xiàn)了某種錯(cuò)誤,此時(shí)可以通過(guò)調(diào)用函數(shù)regerror()得到詳細(xì)的錯(cuò)誤信息。 
            size_t regerror(
          int errcode, const regex_t *preg, char *errbuf,size_t errbuf_size);
            參數(shù)errcode是來(lái)自函數(shù)regcomp()或regexec()的錯(cuò)誤代碼,而參數(shù)preg則是由函數(shù)regcomp()得到的編譯結(jié)果,其目的是把格式化消息所必須的上下文提供給regerror()函數(shù)。在執(zhí)行函數(shù)regerror()時(shí),將按照參數(shù)errbuf_size指明的最大字節(jié)數(shù),在errbuf緩沖區(qū)中填入格式化后的錯(cuò)誤信息,同時(shí)返回錯(cuò)誤信息的長(zhǎng)度。 

            
          5)應(yīng)用正則表達(dá)式 
            例如匹配電話號(hào)碼和Email的例子
          #include   
          <sys/types.h>
          #include   
          <regex.h>
          #include   
          <stdio.h>
          /*******************************************
          *pattern:正則表達(dá)式,str:待檢測(cè)的字符串
          *如果匹配返回0,否則返回-1
          *******************************************
          */
          int     regMatch(char * pattern,char * str){
                  
          int             ret=-1;
                  regex_t         reg;
                  regmatch_t      match
          ={0,0};
                  
          if(regcomp(&reg,pattern,REG_EXTENDED)==0)
                      ret
          =regexec(&reg,str,1,&match,0);
                  regfree(
          &reg);
                  
          return ret;
          }
          int   main(int   argc,   char   *argv[])
          {
                  printf(
          "ret=%d\n",regMatch("^[0-9]\{3,4}-[0-9]\{7,8}$","0592-1234567"));
                  printf(
          "ret=%d\n",regMatch("^[a-z0-9A-Z_-]+@([a-z0-9A-Z_-]+\\.)+[a-z0-9A-Z_-]+$","zeng_chao_1984@163.com"));
                  
          return   0;
          }
            例如返回匹配結(jié)果的例子
          #include   
          <sys/types.h>
          #include   
          <regex.h>
          #include   
          <stdio.h>
          int   main(int argc, char *argv[])
          {
                  regex_t   prog;
                  regmatch_t   match
          ={0,0};
                  
          char   *pattern="[0-9]+";
                  
          char   *string="12 3456 3456y 7890",*s;

                  regcomp(
          &prog, pattern, REG_EXTENDED);
                  s
          = string;
                  
          while(regexec(&prog,s, 1,&match,0)==0)
                  {
                          printf(
          "match at offset %d,length %d\n",s-string+match.rm_so,match.rm_eo-match.rm_so);
                          s
          +=match.rm_eo;
                  }
                  regfree(
          &prog);
          }


               ☆make命令
            使用make命令的幾個(gè)優(yōu)點(diǎn):
            
          1)只編譯修改過(guò)的程序。例如一個(gè)大的項(xiàng)目包含上百個(gè)程序,如果只修改其中一小部分需要測(cè)試,這時(shí)使用make會(huì)只重新編譯修改過(guò)的程序,而不會(huì)全部編譯。
            
          2)make命令能確定不同文件之間的依賴關(guān)系,可以定義宏和附加的目標(biāo)文件,可以執(zhí)行多項(xiàng)操作,提高開(kāi)發(fā)效率

            一個(gè)簡(jiǎn)單的make例子(文件命名為makefile)
          CC      
          = cc
          ESQL    
          = $(INFORMIXDIR)/bin/esql
          LIBDIR  
          = /usr/lib

          test:test.o
                  $(ESQL) 
          -o test test.o

            執(zhí)行make命令,輸入make test,如果修改過(guò)顯示如下:
          cc    
          --o test.o test.c
          /home/informix/bin/esql -o test test.o
            如果已經(jīng)是最新的話,不需要重新編譯,顯示如下:
          make: `test
          ' is up to date.


               ☆memcpy
          函數(shù)原型:extern void *memcpy(void *dest, void *src, unsigned int count); 
          用法:#include 
          <string.h> 
          功能:由src所指內(nèi)存區(qū)域復(fù)制count個(gè)字節(jié)到dest所指內(nèi)存區(qū)域。 
          說(shuō)明:src和dest所指內(nèi)存區(qū)域不能重疊,函數(shù)返回指向dest的指針。 
          運(yùn)用1:實(shí)現(xiàn)Java中的淺度克隆
          typedef 
          struct 
          {
              
          int id;
          } structA;
          int main(){
              structA a
          ==(structA *)malloc(sizeof(structA));
              a.id
          =1;
              structA b
          ==(structA *)malloc(sizeof(structA));
              memcpy(b,a,
          sizeof(b));
              
          return 0;
          }
          運(yùn)用2:實(shí)現(xiàn)Java中的深度克隆
          typedef 
          struct 
          {
              
          int charLen;
              
          char* charA;
          } structB;

          typedef 
          struct 
          {
              structB
          * b;
          } structA;

          typedef 
          struct 
          {
              structA
          * a;
          } testStruct;

          structB b;
          structA a;

          testStruct 
          *des,src;
          int main()
          {
              
          char *p="test";
              b.charA
          =p;
              b.charLen
          =strlen(p);
              a.b
          =&b;
              src.a
          =&a;

              printf(
          "%s\n",src.a->b->charA);

              
          /* 一級(jí)一級(jí)分配空間*/
              des
          =(testStruct*)malloc(sizeof(testStruct));
              des
          ->a=(structA*)malloc(sizeof(structA));
              des
          ->a->b=(structB*)malloc(sizeof(structB));
              des
          ->a->b->charA=(char*)malloc(sizeof(p));

              
          /*深度復(fù)制*/
              memcpy(des,
          &src,sizeof(testStruct));
              printf(
          "%s\n",des->a->b->charA);

              
          /*一級(jí)一級(jí)釋放空間*/
              
          /*先釋放最里面指針的空間,然后外層,否則會(huì)引起內(nèi)存泄露*/
              free(des
          ->a->b->charA);
              free(des
          ->a->b);
              free(des
          ->a);
              free(des);

              
          return 0;
          }


               ☆查找最先出現(xiàn)的任意指定字符strtpbrk()
            表頭文件:#include<string.h>
            函數(shù)定義
          char * strpbrk(const char *s,const char * accept);
            函數(shù)說(shuō)明:strpbrk()用來(lái)查找在字符串s中最先出現(xiàn)的accept中的任意一個(gè)字符的位置;
            返回值:如果找到指定的字符則返回該字符所在地址,否則返回0;
            例如
              
          int     main(){
                  
          char a[10]="abcdefgh";
                  
          char * p=NULL;
                  p
          =strpbrk(a,"123d45");
                  printf(
          "%s\n",p);
                  
          return 0;
              }
              輸出結(jié)果:defgh


               ☆查找指定的字符串strstr()
            表頭文件:#include<string.h>
            函數(shù)定義
          char * strstr(const char *str,const char * s);
            函數(shù)說(shuō)明:strstr()用來(lái)查找在字符串str中最先出現(xiàn)字符串s的位置;
            返回值:如果找到指定的字符串則返回該字符串所在地址,否則返回0;
            例如
              
          int     main(){
                  
          char a[10]="abcdefgh";
                  
          char * p=NULL;
                  p
          =strpbrk(a,"def");
                  printf(
          "%s\n",p);
                  
          return 0;
              }
              輸出結(jié)果:defgh


          posted on 2007-09-25 10:45 破繭而出 閱讀(1007) 評(píng)論(0)  編輯  收藏 所屬分類: C/C++
          主站蜘蛛池模板: 斗六市| 庄河市| 嵊泗县| 宿迁市| 新宾| 云林县| 洛浦县| 扶风县| 北海市| 兰坪| 玛曲县| 兴海县| 灌阳县| 江阴市| 长岛县| 恭城| 岗巴县| 原阳县| 锡林郭勒盟| 彰化市| 郁南县| 麦盖提县| 汝阳县| 甘谷县| 兴和县| 全州县| 康乐县| 海淀区| 东丰县| 拜泉县| 小金县| 万盛区| 承德市| 虎林市| 台安县| 乡宁县| 桦川县| 吐鲁番市| 泽州县| 叶城县| 孝昌县|