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,否则没有赋值''
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
",revbuf[i]);
        printf("%s
",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
", 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;
}
原文地址:https://www.cnblogs.com/mrguoguo/p/13743291.html