1. 程式人生 > >一些常用函式,as:strnstr,memchr。。。。。

一些常用函式,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  逆向 尋找字元 並且返回 從指定字元開始的字串

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,錯誤原因存於errno

8、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);
        }

}