一些常用函式,as:strnstr,memchr。。。。。
1‘ strnstr
//
從 s 串 中 找到 子串 find 並且 返回 find 在s 中的 位置
slen表示find 的長度!。。
1 #include<stdio.h> 2 #include<string.h> 3 char *strnstr( char *s, char *find, size_t slen) 4 { 5 char c, sc; 6 size_t len; 7 8 if ((c = *find++) != '\0') { 9 len = strlen(s); 10 do { 11 do { 12 if (len-- < 1 || (sc = *s++) == '\0') 13 return (NULL); 14 printf("sc:%c,len=%d\n",sc,len); 15 } while (sc != c); 16 if (slen > len) 17 return (NULL); 18 } while (strncmp(s, find, slen-1) != 0); 19 s--; 20 } 21 return ((char *)s); 22 } 23 24 int main() 25 { 26 char *sp="woaichenpeiqing"; 27 char *ds="chen"; 28 printf("%s\n",strnstr(sp,ds,strlen(ds))); 29 return 0; 30 } ~
2、memchr
原型:extern void *memchr(const void *buf, int ch, size_t count); 用法:#include <string.h> 功能:從buf所指記憶體區域的前count個位元組查詢字元ch。 說明:當第一次遇到字元ch時停止查詢。如果成功,返回指向字元ch的指標;否則返回NULL。 舉例: // memchr.c #include <syslib.h> #include <string.h> main() { char *s="Hello, Programmers!"; char *p; clrscr(); p=memchr(s,'P',strlen(s)); //p=(char *)memchr(s,'P',sizeof(s)); //s是一個指向char的指標,而任何指標都是個一個4位元組的數,在這裡應//該是要說明搜尋整個字串的長度,所以應該用strlen(s)if(p) printf("%s",p); else printf("Not Found!"); getchar(); return 0; } ------------------------------------------------------------
3、strchr
strchr函式原型:extern char *strchr(const char *s,char c);查詢字元串s中首次出現字元c的位置。
1
2
3
4
5
6
7
8
char* strchr(char* s,char c)
{
while(*s != '\0' && *s != c)
{
++s;
}
return *s == c ?s:NULL;
}
ps: 與之 相對應的 函式 strrchr 逆向 尋找字元 並且返回 從指定字元開始的字串
4·snprintf()
int snprintf(char *str, size_t size, const char *format, ...);<span style="font-size:18px;">將可變個引數(...)按照format格式化成字串,然後將其複製到str中 (1) 如果格式化後的字串長度 < size,則將此字串全部複製到str中,並給其後新增一個字串結束符('\0'); (2) 如果格式化後的字串長度 >= size,則只將其中的(size-1)個字元複製到str中,並給其後新增一個字串結束符('\0'),返回值為格式化後的字串的長度。 char a[20]; i = snprintf(a, 9, "%012d", 12345); printf("i = %d, a = %s", i, a); 輸出為:i = 12, a = 00000001</span>
5\ strdup
函式名: strdup
功 能: 將串拷貝到新建的位置處
用 法: char *strdup(char *str);
這個函式在linux的man手冊裡解釋為:
The strdup() function returns a pointer toa new string which is a
duplicate of the string s. Memory for thenew string is obtained with
malloc(3), and can be freed with free(3).
The strndup() function is similar, but onlycopies at most n charac-
ters. If s is longer than n, only ncharacters are copied, and a termi-
nating NUL is added.
strdup函式原型:
strdup()主要是拷貝字串s的一個副本,由函式返回值返回,這個副本有自己的記憶體空間,和s不相干。strdup函式複製一個字串,使用完後要記得刪除在函式中動態申請的記憶體,strdup函式的引數不能為NULL,一旦為NULL,就會報段錯誤,因為該函式包括了strlen函式,而該函式引數不能是NULL。
strdup的工作原理:
char * __strdup (const char *s)
{
size_t len =strlen (s) + 1;
void *new =malloc (len);
if (new == NULL)
return NULL;
return (char *)memcpy (new, s, len);
}
例項1:
C/C++ code
#include <stdio.h>
#include <string.h>
#include <alloc.h>
int main(void)
{
char *dup_str,*string = "abcde";
dup_str =strdup(string);
printf("%s\n", dup_str);free(dup_str); return 0;
}
例項2:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
unsigned int Test()
{
charbuf[]="Hello,World!";
char* pb =strndup(buf,strlen(buf));
return (unsignedint)(pb);
}
int main()
{
unsigned int pch= Test();
printf("Testing:%s\n",(char*)pch);
free((void*)pch);
return 0;
}
在Test函式裡使用strndup而出了Test函式仍可以操作這段記憶體,並且可以釋放。
由這個問題而延伸出來的問題就是,如何讓函式得到的記憶體資料傳出函式但仍可用。
解決方法目前本人只想到兩個: 一個外部變數,如傳遞一個記憶體塊指標給函式,但這種做法就是你得傳遞足夠的記憶體,也就是你不能事先知道這個函式到底要多大的BUFFER。
另一種方法就是在函式內部申請static變數,當然這也是全域性區的變數,但這種做法的缺點就是,當函式多次執行時,static變數裡面的資料會被覆蓋。這種型別的另一個方法就是使用全域性變數,但這和使用static變數很相同,不同的是全域性變數可以操作控制,而static變數如果不把它傳出函式,就不可對它操作控制了。另一類方法就是上面所述的,利用堆裡的記憶體來實現,但存在危險。strdup是從堆中分配空間的!strdup呼叫了malloc,所以它需要釋放!對於堆疊:堆是由程式設計師來管理的,比如說new,malloc等等都是在堆上分配的!
棧是由編譯器來管理的。
6、remove 標頭檔案:#include <stdio.h>定義函式:int remove(const char * pathname);
函式說明:remove()會刪除引數pathname 指定的檔案. 如果引數pathname 為一檔案, 則呼叫unlink()處理,若引數pathname 為一目錄, 則呼叫rmdir()來處理. 請參考unlink()與rmdir(). 返回值:成功則返回0, 失敗則返回-1, 錯誤原因存於errno.
7、rename
#include <stdio.h> int rename(const char *oldname, const char *newname); 函式說明 (1) 如果oldname為一個檔案而不是目錄,那麼為該檔案更名。在這種情況下,如果newname作為一個目錄已存在,則它不能重新命名一個目錄。如果newname已存在,而且不是一個目錄,則先將其刪除然後將oldname更名為newname。對oldname所在目錄以及newname所在的目錄,呼叫程序必須具有寫許可權,因為將更改這兩個目錄。 (2) 如若oldname為一個目錄,那麼為該目錄更名。如果newname已存在,則它必須是一個目錄,而且該目錄應當是空目錄(空目錄指的是該目錄中只有. 和.. 項)。如果newname存在(而且是一個空目錄),則先將其刪除,然後將oldname更名為newname。另外,當為一個目錄更名時,newname不能包含oldname作為其路徑字首。例如,不能將/usr更名為/usr/foo/testdir,因為老名字( /usr/foo)是新名字的路徑字首,因而不能將其刪除。 (3) 作為一個特例,如果oldname和newname引用同一檔案,則函式不做任何更改而成功返回。 返回值 執行成功則返回0,失敗返回-1,錯誤原因存於errno8、mmap
mmap將一個檔案或者其它物件對映進記憶體。檔案被對映到多個頁上,如果檔案的大小不是所有頁的大小之和,最後一個頁不被使用的空間將會清零。
#include <sys/mman.h> void *mmap(void *start, size_t size, int prot, int flags,int fd, off_t offset); int munmap(void *start, size_t size);條件:
mmap()必須以PAGE_SIZE()為單位進行對映,而記憶體也只能以頁為單位進行對映,若要對映非PAGE_SIZE整數倍的地址範圍,要先進行記憶體對齊,強行以PAGE_SIZE的倍數大小進行對映。start:對映區的開始地址,設定為0時表示由系統決定對映區的起始地址。 length:對映區的長度。//長度單位是 以位元組為單位,不足一記憶體頁按一記憶體頁處理 prot:期望的記憶體保護標誌,不能與檔案的開啟模式衝突。是以下的某個值,可以通過or運算合理地組合在一起 PROT_EXEC //頁內容可以被執行 PROT_READ //頁內容可以被讀取 PROT_WRITE //頁可以被寫入 PROT_NONE //頁不可訪問 flags:指定對映物件的型別,對映選項和對映頁是否可以共享。它的值可以是一個或者多個以下位的組合體 MAP_FIXED //使用指定的對映起始地址,如果由start和len引數指定的記憶體區重疊於現存的對映空間,重疊部分將會被丟棄。如果指定的起始地址不可用,操作將會失敗。並且起始地址必須落在頁的邊界上。 MAP_SHARED //與其它所有對映這個物件的程序共享對映空間。對共享區的寫入,相當於輸出到檔案。直到msync()或者munmap()被呼叫,檔案實際上不會被更新。 MAP_PRIVATE //建立一個寫入時拷貝的私有對映。記憶體區域的寫入不會影響到原檔案。這個標誌和以上標誌是互斥的,只能使用其中一個。 MAP_DENYWRITE //這個標誌被忽略。 MAP_EXECUTABLE //同上 MAP_NORESERVE //不要為這個對映保留交換空間。當交換空間被保留,對對映區修改的可能會得到保證。當交換空間不被保留,同時記憶體不足,對對映區的修改會引起段違例訊號。 MAP_LOCKED //鎖定對映區的頁面,從而防止頁面被交換出記憶體。 MAP_GROWSDOWN //用於堆疊,告訴核心VM系統,對映區可以向下擴充套件。 MAP_ANONYMOUS //匿名對映,對映區不與任何檔案關聯。 MAP_ANON //MAP_ANONYMOUS的別稱,不再被使用。 MAP_FILE //相容標誌,被忽略。 MAP_32BIT //將對映區放在程序地址空間的低2GB,MAP_FIXED指定時會被忽略。當前這個標誌只在x86-64平臺上得到支援。 MAP_POPULATE //為檔案對映通過預讀的方式準備好頁表。隨後對對映區的訪問不會被頁違例阻塞。 MAP_NONBLOCK //僅和MAP_POPULATE一起使用時才有意義。不執行預讀,只為已存在於記憶體中的頁面建立頁表入口。 fd:有效的檔案描述詞。一般是由open()函式返回,其值也可以設定為-1,此時需要指定flags引數中的MAP_ANON,表明進行的是匿名對映。 offset:被對映物件內容的起點。 9、memcmp (我去 我看成了 memcpy) 靠了 int memcmp(const void *buf1, const void *buf2, unsigned int count);
#include <string.h>或#include<memory.h>
當buf1<buf2時,返回值<0 當buf1=buf2時,返回值=0 當buf1>buf2時,返回值>0 該函式是按位元組比較的。 例如: s1,s2為字串時候memcmp(s1,s2,1)就是比較s1和s2的第一個位元組的ascII碼值; memcmp(s1,s2,n)就是比較s1和s2的前n個位元組的ascII碼值; 如:char *s1="abc"; char *s2="acd"; int r=memcmp(s1,s2,3); 就是比較s1和s2的前3個位元組,第一個位元組相等,第二個位元組比較中大小已經確定,不必繼續比較第三位元組了。所以r=-1.
#include<string.h>
#include<stdio.h>
main()
{
char *s1="Hello, Programmers!";
char *s2="Hello, programmers!";
int r;
r=memcmp(s1,s2,strlen(s1));
if(!r)
printf("s1 and s2 are identical\n"); /*s1等於s2*/
else if(r<0)
printf("s1 is less than s2\n"); /*s1小於s2*/
else
printf("s1 is greater than s2\n"); /*s1大於s2*/
return 0;
}
10、access && mkdir
#include<sys/stat.h>
#include<sys/types.h>
#include<sys/errno.h>
#include<unistd.h>
#define TMP_LOG_FILE_DIR "/tmp/lcf/log"
int main()
{
/* char *ac_dir = "/tmp/log";
if(access(ac_dir, F_OK)==-1)
{
printf("file not sucess\n");
}
printf("tmp/lcf have exits\n");
char *dir = "/tmp/log/";
if(mkdir(dir, 655) != 0)
{
if(errno != EEXIST)
{
perror("mkdir");
exit(-1);
}
}*/
if(access(TMP_LOG_FILE_DIR, F_OK)==-1)
{
printf("failed\n");
char dir_log[126]={'\0'};
snprintf(dir_log, 126, "mkdir -p %s", TMP_LOG_FILE_DIR);
system(dir_log);
}
}