• 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;
    }
  • 相关阅读:
    android开发 PopupWindow 设置充满屏幕
    android 设置半透明
    web farm 讨论引出
    xamarin studio And linq 查询方式分析
    MONO 使用重要提示
    一个MVC的在线编译工具
    MONO Jexus部署最佳体验
    Origami
    产品原型设计工具 Balsamiq Mockups(转)
    VSPM虚拟串口使用
  • 原文地址:https://www.cnblogs.com/mrguoguo/p/13743291.html
Copyright © 2020-2023  润新知