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);
}
{
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));
}
定義函數(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ù):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é)束。
表頭文件:<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" );
}
定義函數(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地址的空間。
例如:
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)的空間分配給程序。
釋放空間: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ǔ)言里面顯式的分配和釋放。
棧是線程獨(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è)字符指針)
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;
}
表頭文件:<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));
}
表頭文件:<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(®,pattern,REG_EXTENDED)==0)
ret=regexec(®,str,1,&match,0);
regfree(®);
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);
}
使用正則表達(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(®,pattern,REG_EXTENDED)==0)
ret=regexec(®,str,1,&match,0);
regfree(®);
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 -c -o test.o test.c
/home/informix/bin/esql -o test test.o
如果已經(jīng)是最新的話,不需要重新編譯,顯示如下:
make: `test' is up to date.
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 -c -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;
}
用法:#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
函數(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
函數(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