發新話題

[教學]要問字串問題之前,先來這裡翻一下

[教學]要問字串問題之前,先來這裡翻一下

字串問題也是很多新手超愛問的,整理這一篇,希望能讓一些較簡易的問題就直接導向這裡

C語言的字串操作

字串的宣告
  一般只要是用 " 符號所包起來的字元就是字串,如下的宣告
  char s[5]="abcd";
  字串"abcd"除了四個字元所佔的空間外還包含一個'\0'字元在最後面當字串結束符號
  所以總字元數是5
  字串就是一連續字元的最末端以一個'\0'字符做為結束的連續字元
  編譯器對字串的處理以及字串相關的函式,都是依照這個規格在處理字串,這也是字串與一般字元陣列不一樣的地方
  你也可以這樣子來宣告char s[]="abcd";
  雖沒有指明陣列索引值,但編譯器會自動幫你補上,所以陣列 s 將會是一個索引值為 5 的陣列

字串與char*
  以下是一個最簡單的應用
  char s[]="abcd";
  char* p=s;
  p 就相當於是一個指著 s 的指標
  
  char* str="abcd";
  指標str相當於是一個字串,編譯器會自動配置一塊空間擺放"abcd"這個字串,然後讓str指標指向它
  但他和char s[]是不一樣的地方,是你不能修改那塊空間裡的值,像這樣 *str='z';
  但你能再讓他指向別的地方
  
字串的處理
  C裡頭有一組現成的專用拿來處理字串的函式,需引入 string.h 這個標頭檔
  以下簡單的介紹這些常用的函式
  
  size_t strlen(const char* source)
    取得字串長度
   
  char* strcpy(char* destn,const char* source)
    拷貝字串,將source字串拷貝至destn的空間,回傳值其實就是destn的位置
   
  char* strncpy(char* destn,const char* source,size_t n)
    拷貝字串,將source字串的前n個字元拷貝至destn的空間,回傳值為destn的位置
   
  char* strcat(char* destn,const char* source)
    穇筐潀r串,將source字串串接至destn字串後面,回傳值為destn的位置,請確定destn的空間足夠儲放串接後的字串
   
  char* strncat(char* destn,const char* source,,size_t n)
    串接兩字串,將source的前n個字串串接至destn字串後面,回傳值為destn的位置,請確定destn的空間足夠儲放串接後的字串
   
  int strcmp(const char* str1,const char* str2)
    比對字串,若完全相等則回傳0,若有差異,回傳其字元值差
   
  int strncmp(const char* str1,const char* str2,size_t n)
    比對字串只比對前n個字元,若完全相等則回傳0,若有差異,回傳其字元值差
   
  int strcasecmp(const char* str1,const char* str2)
    忽略大小寫比對字串,比對字串,若完全相等則回傳0,若有差異,回傳其字元值差
   
  int strncasecmp(const char* str1,const char* str2,size_t n)
    忽略大小寫比對字串只比對前n個字元,若完全相等則回傳0,若有差異,回傳其字元值差
  
  char* strchr(const char* str,int ch)
    找出字串中第一個指定字元的位置,若找不到傳回0
   
  char* strrchr(const char* str,char ch)
    找出str字串中,最後一個出現ch字元的字元,回傳該字元位址
    char str[]="123123";
    strrchr(str,'1');
    回傳值將會是&str[3]
   
  size_t strcspn(const char* str,const char* reject)
    傳回str字串中第一個不含reject字串中字元的前字元數
    char str[]="ABCD123456789";
    strcspn(str,"4321");
    將會得到4
   
  char* strdup(const char* string)
    複製字串,其字串空間是使用molloc()所配置,事後也能用free()釋放掉,失敗回傳NULL
   
  char* strfry(char* string)
    隨機重組字串內的字元
   
  char* strpbrk(const char* str,const char* accept)
    找出str字串中,有accept字串中字元的字元,回傳該字元的位址
    char str[]="ABCD123456789";
    strpbrk(str,"4321");
    回傳值將會是&str[4]
   
  char* strrchr(const char* str,char ch)
    找出str字串中,最後一個出現ch字元的字元,回傳該字元位址
    char str[]="123123";
    strrchr(str,'1');
    回傳值將會是&str[3]
   
  size_t strspn(const char* str,const char* accept)
    傳回str字串中前面含有accept字串中字元的字元數
    char str[]="ABCD123456789";
    strspn(str,"BA");
    將會得到2
   
  char* strstr(const char* str1,const char* str2)
    搜尋字串,在str1的字串搜尋str2字串,傳回搜尋到的子字串位址
   
  char* strtok(char* str,const char* delimit)
    分解字串,str字串為要被分解的字串,delimit為要做為分解依據的字串
    找到了要分解依據的字元便將其設為='\0',即回傳該字串
    第一次使用strtok()引數str必須指定,往後可設為NULL,如此將持續一直分解下去,直到回傳值為NULL,便不能再分解下去
    char str[]="abc def:ghi-xyz try"
    char* p;
    printf("%s=",strtok(str," :-"));
    while(p=strtok(NULL," :-"))printf("%s=",p);
    將印出 abc=def=ghi=xyz=try
     
  以上所例函式從較常用者先列出string.h不只有專用處理字串的函式,也有專門用來處理記憶體的相關函式
  它們的差別在於字串函式處理的對象是字串,也就是'\0'符號做為結尾的一串字元,所傳入的char*型別的參數都必須要是字串  
  而記憶體函式是不管內容是什麼字元,都一視同仁處理
  
  void* memcpy(void* destn,const void* source,size_t n)
    記憶體拷貝,從soutce中拷貝n個字元至destn,回傳值為destn位址
   
  void* memccpy(void* destn,const void* source,int ch,size_t n)
    記憶體拷貝,從soutce中拷貝n個字元至destn,但若出現ch字元時即中斷拷貝,並回傳出現ch字元的下一個字元的位址
    若未出現ch字元則回傳0
   
  int memcmp(const void* mem1,const void* mem2,size_t n)   
    記憶體比對,比對mem1和mem2所指的記憶體空間的前n個字元,回傳值為相異的字元差
   
  void* memchr(const void* mem,int ch,size_t n)
    搜尋mem記憶體內容的前n個字元是否有ch字元,回傳值為該ch字元的位址,若無則回傳0
  
  void* memmove(void* destn,const void* source,size_t n)
    記憶體拷貝,從soutce中拷貝n個字元至destn,但destn和source的區域若有重疊,也能進行拷貝
    但執行效率比memcpy()略慢些
  
  void* memset(void* mem,int ch,size_t n)
    將mem記憶體內容的前n個位元組以ch值填入  
  
  int ffs(int i)  
    由low位元至high位元,判斷i位元組中的位元,將其第一個出現true的位數傳回
    int i[]={1,2,4,8,16,32,64};
    for(int j=0;j<8;++j)
      printf("%d ",ffs(i[j]));
    將印出 0 1 2 3 4 5 6 7
  
  char* index(const char* str,int ch)
    找尋str字串中第一個出現的ch字元,回傳該位置(能尋找字串結束符號位置)
   
  char* rindex(const char* str,int ch)
    找尋str字串中最後一個出現的ch字元,回傳該位置(能尋找字串結束符號位置)

但在開發 高階應用程式 我是建議使用人家已經設計好的 String 類別 可以減少錯誤


一般字串沒所謂的等號 不像 A=2; B=A; 這樣的描述
結構也沒有 A=B 除非你你去重載運算子=號
所以遇到這樣的問題 通常要靠拷貝一份資料過去

struct sTEST
{
int a,b,c,d;
};

sTEST m_s1,m_s2;

當m_s2內容要跟m_s1一樣 不可以直接這樣描述m_s2=m_s1;
但可以靠拷貝把整各結構COPY過去
memcpy(&m_s2,&m_s1,sizeof(sTEST));


字串也是一樣但要注意copy過去是否 產生溢位
char temp1 [256];
char temp2[128];

memcpy(temp2,temp1,sizeof(temp1));   //這樣會產生溢位 但程式編譯不會出錯 大到小的容器 要注意使用



[ 本帖最後由 philxyz0316 於 2006-8-27 13:06 編輯 ]

TOP

發新話題

本站所有圖文均屬網友發表,僅代表作者的觀點與本站無關,如有侵權請通知版主會盡快刪除。