C的字符串操作 split


1.char*和char[]都可以表示字符串

2.char[]可讀可寫,可以修改字符串的內容。char*可讀不可寫,寫入就會導致段錯誤(具體原因不清楚)

因此可以解釋,當直接對char*類型的指針變量寫入數據時,會導致段錯誤,需要使用char[]

1、char *a = "hello" 中的a是指向第一個字符bai‘a'的一個指針

2、char a[20] = "hello" 中數組du名a也是執行數組第一個字符‘h’的指針

但二者並不相同:看實例:把兩個字符串相加

顯示結果:hello0123456789   顯示結果:segmentation fault

 

 

把字符串加到指針所指的字串上去,出現段錯誤,本質原因:*d="0123456789"存放在常量區,是無法修的。而數組是存放在棧中,是可以修改的。兩者區別如下:

1、 ”讀“ ”寫“ 能力

char *a = "abcd";  此時"abcd"存放在常量區。通過指針只可以訪問字符串常量,而不可以改變它

而char a[20] = "abcd"; 此時 "abcd"存放在棧。可以通過指針去訪問和修改數組內容

2、賦值時刻

char *a = "abcd"; 是在編譯時就確定了(因為為常量)

而char a[20] = "abcd"; 在運行時確定

3、 存取效率

char *a = "abcd"; 存於靜態存儲區。在棧上的數組比指針所指向字符串快。因此慢

而char a[20] = "abcd"; 存於棧上

我們知道一點,*代表取值符。
其次,我們要明白一點,以為*p可指向以zhi為數組,**p指向二維數組,***p指向三dao維數組......
最后()在不同的情況下有不同的含義。好現在開始講解*char(**)與(char*)的區別
1、*char(**)應該表示一個指向二維數組的指針,其效果等同於一個三維數指針
2、(char*)我給出以下兩種含義:
a、可定義一個字符型指針
b、將當前對象顯示轉換為字符指針類型

 

 

 

1.char[]轉char*   直接進行賦值即可

#include<iostream>
#include<string.h>
using namespace std;
 
int main(){
    //char[] 轉 char*
    char ch[]="abcdefghijklmn";
    char *s = ch;
    cout<<s<<endl; 
    return 0;
}

 

2.char*轉char[]  字符拷貝實現,不能進行賦值操作

#include<iostream>
#include<string.h>
using namespace std;
 
int main(){
    //char* 轉 char[]
    char *s="abcdefghijklmn";
    char  ch[100];
    strcpy(ch,s);
    cout<<ch<<endl; 
    return 0;
}

 

3.char* 與const char* 之間轉換   直接進行賦值  反之 拷貝

// char *轉const char *
char *st = "hehe"; // (編譯提示警告)
const char *st1 = st;
cout << st1 << endl;

 

// const char *轉char *
const char *st = "lala";
// 直接賦值不可以
//char *st1 = st; // (不可以編譯器報錯)
//cout << st1 << endl;
// 另外開辟空間,將字符一個一個復制過去
char *ncstr = new char[strlen(st) + 1];
strcpy(ncstr, st);
cout << ncstr << endl;

4.char* 與 string 之間轉換 1)直接賦值;2)構造轉換實現

     

// char*轉換為string
// (注意,定義char *變量,並直接賦值,最好定義為const變量,否則編譯器警告)
const char *st = "hello";
// 賦值轉換
string st1 = st;
cout << st1 << endl;
// 構造轉換
string s1(st, st + strlen(st));
cout << s1 << endl;
// 改變const char *變量值
st = "lalala";
cout << st << endl;

string轉char *:賦值操作(注意類型轉換)

// string轉char *
string st = "My test";
//char *st1 = st; // 錯誤類型不同
//char *st1 = st.c_str(); // 錯誤類型不同
char *st1 = const_cast<char *>(st.c_str()) ;
cout << st1 << endl;

 

5.char[] 與 string 之間轉換    string轉char[]:拷貝實現,不能直接賦值

 
        
 
        
char []轉string:1)直接賦值;2)構造轉換實現

// char[]轉換為string
char st[] = "hello";
// 直接賦值實現
string st1 = st;
cout << st1 << endl;
// 構造實現
string st2(st, st + strlen(st));
cout << st2 << endl;

string轉char[]:拷貝實現,不能直接賦值

// string轉char []
string ts = "My test1";
//char ts1[] = ts; // 錯誤
//char ts1[] = const_cast<char *>(ts.c_str()); // 錯誤
char ts1[] = "lalallalalaaaa";
strncpy(ts1, ts.c_str(), ts.length() + 1); // 注意,一定要加1,否則沒有賦值'\0'
cout << ts1 << endl;
return 0;

 

所以當我們在C里要處理一個  char*  類型的數據 那么就需要 我們轉成 char[]

vs2019 中是這樣的

    char *str1 = (char *) "This is - www.666.com - website";
    char str[] = {0};
        strcpy(str,str1);// "This is - www.666.com - website";
     char s[2] = "-";
    char* token;
    char* dest[8] = { 0 };
    int num = 0;
    split(str,s,dest,&num);

 

 

方式一:
使用strtok

# include <string.h>
# include <stdio.h>

void split(char *src,const char *separator,char **dest,int *num) {
    /*
        src 源字符串的首地址(buf的地址) 
        separator 指定的分割字符
        dest 接收子字符串的數組
        num 分割后子字符串的個數
    */
     char *pNext;
     int count = 0;
     if (src == NULL || strlen(src) == 0) //如果傳入的地址為空或長度為0,直接終止 
        return;
     if (separator == NULL || strlen(separator) == 0) //如未指定分割的字符串,直接終止 
        return;
     pNext = (char *)strtok(src,separator); //必須使用(char *)進行強制類型轉換(雖然不寫有的編譯器中不會出現指針錯誤)
     while(pNext != NULL) {
          *dest++ = pNext;
          ++count;
         pNext = (char *)strtok(NULL,separator);  //必須使用(char *)進行強制類型轉換
    }  
    *num = count;
}     

int main(){
    int i;
    char buf[]="www.baidu.com,www.taobao.com,www.csdn.com,www.python.org";
    //用來接收返回數據的數組。這里的數組元素只要設置的比分割后的子字符串個數大就好了。
    char *revbuf[8] = {0}; //存放分割后的子字符串 
    
    //分割后子字符串的個數
    int num = 0;
    
    split(buf,",",revbuf,&num); //調用函數進行分割 
    
    
    //輸出返回的每個內容 
    for(i = 0;i < num; i ++) {
        //lr_output_message("%s\n",revbuf[i]);
        printf("%s\n",revbuf[i]);
    }


    return 0;
}

 

方式二:
使用strchr

 

void split(char * p,char * str){
    /*
        傳入一個數組進行p和一個以什么進行分割的str,返回切片后的值
    */ 
    
    int i = 0, j = 0;
    char tmp[32][32] = {0};
    char *p1 = (char *)malloc(1024);
 
    while((p1 = (char *)strchr(p, *str)) != NULL) //必須使用(char *)進行強制類型轉換
    {
        strncpy(tmp[i], p, strlen(p) - strlen(p1));
        p = p1 + 1;
        i ++;
    }
    strncpy(tmp[i], p, strlen(p));
 
    for(j = 0; j <= i; j++){
        lr_output_message("tmp[%d] = %s\n", j, tmp[j]);
    }
}
 
Action (){

    char p[] = "www.baidu.com,www.taobao.com,www.csdn.com,www.python.org";
    char str[] = ","; //分割的字符串 
    split(p,str);
 
    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM