posts - 108,comments - 56,trackbacks - 0
               ☆去掉首尾空格的函數
            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);   
            }  


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

          返回值:若參數s1和s2所指定的內存內容都完全相同則返回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()函數
             sprintf跟printf在用法上差不多,只是打印的目的地不同,前者打印到字符串中,后者直接在命令行上輸出。
             定義函數:
          int sprintf( char *buffer, const char *format [,argument]  );
             經典用途:格式化數字字符串;連接字符串(可以連接多個,比strcat強)。
             注意:小心第一個參數的長度不夠。為了安全,可以使用
          %.ns來控制輸出參數的最多個數。而且好像buffer不是申明為字符數組會報錯。
             范例:
             #include <stdio.h>
            int main(void){
               char * a="abcdefg";
               char b[15];
               sprintf(b,"%.7s",a);
               printf("result=%s\n",b);
            }


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


               ☆atexit
             注冊一個給定的函數,該函數在程序exit時候被調用。(不管是通過exit(3)或者還是通過從程序的main函數中返回)。 注冊的函數是反序被調用的;沒有參數。至少32個函數總是可以被注冊的,只要有充分的分配的內存,更多的函數也是允許的。
             定義函數
          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
             如果在運行的時候,非法訪問內存就會出現"segmentation fault"的結果。
             例如:
             
          int i=100;
             printf(
          "%s",i);
             這樣會直接取訪問100地址的空間。


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

              malloc從哪里得到空間:
              從堆里面獲得空間。也就是說函數返回的指針是指向堆里面的一塊內存。操作系統中有一個記錄空閑內存地址的鏈表。當操作系統收到程序的申請時,就會遍歷該鏈表,然后就尋找第一個空間大于所申請空間的堆結點,然后就將該結點從空閑結點鏈表中刪除,并將該結點的空間分配給程序。


               ☆堆/棧
              是大家共有的空間,分全局堆和局部堆。全局堆就是所有沒有分配的空間,局部堆就是用戶分配的空間。堆在操作系統對進程初始化的時候分配,運行過程中也可以向系統要額外的堆。
              是線程獨有的,保存其運行狀態和局部自動變量的。棧在線程開始的時候初始化,每個線程的棧互相獨立。每個函數都有自己的棧,棧被用來在函數之間傳遞參數。操作系統在切換線程的時候會自動的切換棧,就是切換SS
          /ESP寄存器。棧空間不需要在高級語言里面顯式的分配和釋放。


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


               ☆分解字符串(類似JAVA中的split)
            定義函數extern char *strtok(char *s, char *delim);     
            表頭文件
          <string.h>
            功能:分解字符串為一組標記串。s為要分解的字符串,delim為分隔符字符串。
            說明:首次調用時,s必須指向要分解的字符串,隨后調用要把s設成NULL。strtok在s中查找包含在delim中的字符并用NULL(
          '\0')來替換,直到找遍整個字符串。返回指向下一個標記串。當沒有標記串時則返回空字符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;
                }


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


               ☆正則表達式
            標準的C不支持正則表達式,但有一些函數庫可以輔助完成這一功能,其中最著名的當數Philip Hazel的Perl-Compatible Regular Expression庫,許多Linux發行版本都帶有這個函數庫。
            使用正則表達式用三個過程:編譯正則表達式
          ->匹配正則表達式->釋放正則表達式

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

            
          2)匹配正則表達式 
            一旦用regcomp()函數成功地編譯了正則表達式,接下來就可以調用regexec()函數完成模式匹配: 
            
          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;
            參數preg指向編譯后的正則表達式,參數string是將要進行匹配的字符串,而參數nmatch和pmatch則用于把匹配結果返回給調用程序,最后一個參數eflags決定了匹配的細節。 
            在調用函數regexec()進行模式匹配的過程中,可能在字符串string中會有多處與給定的正則表達式相匹配,參數pmatch就是用來保存這些匹配位置的,而參數nmatch則告訴函數regexec()最多可以把多少個匹配結果填充到pmatch數組中。當regexec()函數成功返回時,從string
          +pmatch[0].rm_so到string+pmatch[0].rm_eo是第一個匹配的字符串,而從string+pmatch[1].rm_so到string+pmatch[1].rm_eo,則是第二個匹配的字符串,依此類推。 

            
          3)釋放正則表達式 
            無論什么時候,當不再需要已經編譯過的正則表達式時,都應該調用函數regfree()將其釋放,以免產生內存泄漏。 
            
          void regfree(regex_t *preg);
            函數regfree()不會返回任何結果,它僅接收一個指向regex_t數據類型的指針,這是之前調用regcomp()函數所得到的編譯結果。 
            如果在程序中針對同一個regex_t結構調用了多次regcomp()函數,POSIX標準并沒有規定是否每次都必須調用regfree()函數進行釋放,但建議每次調用regcomp()函數對正則表達式進行編譯后都調用一次regfree()函數,以盡早釋放占用的存儲空間。 

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

            
          5)應用正則表達式 
            例如匹配電話號碼和Email的例子
          #include   
          <sys/types.h>
          #include   
          <regex.h>
          #include   
          <stdio.h>
          /*******************************************
          *pattern:正則表達式,str:待檢測的字符串
          *如果匹配返回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;
          }
            例如返回匹配結果的例子
          #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命令的幾個優點:
            
          1)只編譯修改過的程序。例如一個大的項目包含上百個程序,如果只修改其中一小部分需要測試,這時使用make會只重新編譯修改過的程序,而不會全部編譯。
            
          2)make命令能確定不同文件之間的依賴關系,可以定義宏和附加的目標文件,可以執行多項操作,提高開發效率

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

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

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


               ☆memcpy
          函數原型:extern void *memcpy(void *dest, void *src, unsigned int count); 
          用法:#include 
          <string.h> 
          功能:由src所指內存區域復制count個字節到dest所指內存區域。 
          說明:src和dest所指內存區域不能重疊,函數返回指向dest的指針。 
          運用1:實現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;
          }
          運用2:實現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);

              
          /* 一級一級分配空間*/
              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));

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

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

              
          return 0;
          }


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


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


          posted on 2007-09-25 10:45 破繭而出 閱讀(1007) 評論(0)  編輯  收藏 所屬分類: C/C++
          主站蜘蛛池模板: 舒城县| 桃园市| 梨树县| 汕头市| 车致| 昭通市| 富民县| 两当县| 高台县| 宁乡县| 永城市| 河间市| 江永县| 丰城市| 柳林县| 汉中市| 陈巴尔虎旗| 元朗区| 临清市| 宁河县| 普宁市| 张北县| 罗山县| 土默特左旗| 潢川县| 白玉县| 阿坝县| 宜宾市| 平远县| 息烽县| 桃园市| 怀安县| 平利县| 营山县| 武穴市| 临沂市| 东乡县| 琼中| 小金县| 文成县| 哈巴河县|