zoukankan      html  css  js  c++  java
  • C 语言 实现 字符串 分割 函数(返回"二维字符数组",及分割后的字符数组的长度)

       这段时间重拾C语言. 之前只是在大学时草草的学习了一年时间.当然与大部分同学一样.90%以上都还给了老师.  现在只是依稀得记得好像似乎大概学习过~~ 

    为什么要写这个字符串分割的实现呢. 主要也是对这段时间学习的一个总结. 觉得自带的strtok 方法实现得不够方便 .用惯了C# 还是希望他可以直接将 分割后的字串返回. 

    其中也练习了几个知识点:结构体,指针,malloc ,释放内存等...

    View Code
      1 #include <stdio.h>
    2 #include <string.h>
    3 #include <stdlib.h>
    4
    5 struct sstruct //分割后返回的结构体定义
    6 {
    7 char **p; //指向生成的字符数组("二维")
    8 int len; //记录"二维数组"的长度. 也就是被分成了几个字符串
    9 };
    10 //实现字符串按给定的from to值 来拷贝的方法,在分割函数中会用到
    11 void strCopy(char *src,char *dst,int from,int to)
    12 {
    13 int n = 0;
    14 for(int i = from;i<=to;i++)
    15 {
    16 *(dst + n) = *(src + from + n);
    17 n++;
    18 }
    19 *(dst+n) = '\0'; //字串后需要加这个,不要忘了.
    20 }
    21 //字符串分隔函数 返回 sstruct 结构体指针
    22 struct sstruct * strSplit(char arr[],char s)
    23 {
    24 int arrlen = strlen(arr); //得到数组的长度 arrlen
    25 int pos[10]; //定义一个数组,用来存放所找到的字符所在的位置,在这里最多可以放10个. 一般情况10个就够了.
    26 for(int i = 0;i<10;i++) pos[i] = -1; //将 pos 里的内容初始化为 -1
    27
    28 int find = 0;
    29 for(int i =0;arr[i];i++) //在arr 中去寻找 字符 s 将找到的位置放到 pos 中.
    30 {
    31 if(arr[i] == s)
    32 {
    33 pos[find] = i;
    34 find ++;
    35 }
    36 }
    37 int num = (find+1) * 2;
    38 int segs= 0; //真正的有几个段
    39 int segMaxLen = 0; //表示被分割中最长的元素.用这个值 来生成输出的二维数组
    40 int segArr[num]; //将每分割段的两头的值 放入segArr
    41 for(int i = 0;pos[i] != -1;i++) //*分析 pos 数组. 得到分割后的字符域segArr,及真正的段数segs
    42 {
    43 if(i == 0)
    44 {
    45 segMaxLen = pos[0] ; //字串的最大长度
    46 //放入segArr
    47 if(pos[0] == 0 )
    48 {
    49 segArr[0] = -1; //如果 位置在最前 ,最后, 或是两个或 多个分割符连在一起的话 如: @XXX@@@XXX@ 这之间的位给为 -1
    50 segArr[1] = -1;
    51 }
    52 else
    53 {
    54 segArr[0] = 0; //如果是分割符之间存在字符如 3 -- 7 ,则向segArr中写入其之间的值 4 - 6 ,代表,这段被分割的字符串的首尾.
    55 segArr[1] = pos[0]-1;
    56 segs ++; //找到一个合理的,被分割的字符中.segs加1.
    57 }
    58 }
    59 else
    60 {
    61 int tmp =pos[i] -pos[i-1];
    62 segMaxLen = tmp > segMaxLen ? tmp : segMaxLen;
    63 //放入 segArr
    64 if(tmp == 1 )
    65 {
    66 segArr[i*2] = -1;
    67 segArr[i*2+1] = -1;
    68 }
    69 else
    70 {
    71 segArr[i*2] = pos[i-1]+1;
    72 segArr[i*2+1] = pos[i] -1;
    73 segs ++;
    74 }
    75 }
    76 if(pos[i] == arrlen || pos[i+1] == -1) //最后一个. 还要与arr 的总长比较
    77 {
    78 int tmp = arrlen - pos[i];
    79 segMaxLen = tmp > segMaxLen ? tmp :segMaxLen;
    80 if(arrlen - pos[i] == 1)
    81 {
    82 segArr[i*2+2] = -1;
    83 segArr[i*2+3] = -1;
    84 }
    85 else
    86 {
    87 segArr[i*2+2] = pos[i]+1;
    88 segArr[i*2+3] = arrlen;
    89 segs ++;
    90 }
    91 }
    92 }
    93
    94 //*最终得到的需要返回的数组*
    95 char **sstr = (char **)malloc(sizeof(char*)*segs); //***输出的 "二维数组" 的指针***
    96 for(int i = 0;i<segs;i++) //***对里面的内容进行初始化***
    97 *(sstr + i) = (char*)malloc(sizeof(char *)*segMaxLen);
    98
    99 int w = 0;
    100 for(int i = 0;i<num;i+=2)
    101 {
    102 if(segArr[i] != -1)
    103 {
    104 strCopy(arr,*(sstr + w),segArr[i],segArr[i+1]); // 对输出的数组进行赋值
    105 w++;
    106 }
    107 }
    108 //创建输出的结构体
    109 //这里返回的是一个 结构体指针(在结构体不大的时候直接返回结构体会更方便些)
    110 struct sstruct *ww = (struct sstruct *)malloc(sizeof(struct sstruct));
    111 ww->p = sstr;
    112 ww->len = segs;
    113 return ww;
    114
    115 /*
    116 注意: 在这个函数中使用 malloc 为指针,初始开辟的内存空间
    117 要在主函数使用这个方法之后.将其释放.free();
    118 */
    119 }
    120
    121 //主函数
    122 int main()
    123 {
    124 //待分割的串
    125 char str[] = "@ABCdefG@你好~~@hello world@1655@*(^*(^下是另 中";
    126
    127 struct sstruct *ww; //为分隔后返回的结构体创建一个存放的位置
    128 ww = strSplit(str,'@'); //*调用strSplit 方法实现字符串分割*//
    129
    130 //输出 ww->len: 为分割后字符串的数量 ww->p 指向第一个串 用for来输出反有的串 *(w->p + i)
    131 for (int i = 0;i<ww->len;i++)
    132 printf("%s\n",*(ww->p + i));
    133
    134 //释放二维数组的列
    135 for(int i = 0;i<ww->len;i++)
    136 free(*(ww->p + i));
    137 //释放二维数组
    138 free(ww->p);
    139 //释放结构体指针
    140 free(ww);
    141 }



  • 相关阅读:
    剑指offer JZ-1
    侯捷《C++面向对象开发》--String类的实现
    侯捷《C++面向对象开发》--复数类的实现
    辛普森悖论
    马尔可夫链的平稳分布
    熵和基尼指数的一些性质
    UVA 11624 Fire!(广度优先搜索)
    HDU 4578 Transformation (线段树区间多种更新)
    HDU 1540 Tunnel Warfare(线段树+区间合并)
    多重背包
  • 原文地址:https://www.cnblogs.com/easyfrog/p/C_str_split_string.html
Copyright © 2011-2022 走看看