zoukankan      html  css  js  c++  java
  • 1. C/C++项目一

    需求: 使用C语言封装string 字符串,实现字符串的增、删、改、查等API函数。

    要求: 不能使用 string 库函数,所有库函数必须自己手动实现。

     【项目实现】

    myString.h 代码如下:

     1 #include <stdlib.h>
     2 #include <string.h>
     3 #include <stdio.h>
     4 
     5 //字符串封装,需要库函数
     6 //不需要库函数
     7 struct CString
     8 {
     9     char *p;        //保存字符串首地址
    10     int realLen;    //字符串实际长度
    11 };
    12 
    13 typedef struct CString myString;    //相当于myString就是struct CString的简写
    14 
    15 //字符串封装需要实现:初始化、打印、增[尾部增加/任意位置增加](字符/字符串)、删(字符/字符串)、查(字符/字符串)、改(字符/字符串)
    16 
    17 void init(myString *string);                                //原封不动初始化
    18 void initWithLen(myString *string, int len);                //开辟长度,内存清零
    19 void initWithString(myString *string, char *copyString);    //初始化并拷贝字符串
    20 void printString(myString *string);                         //打印字符串
    21 
    22 void run(myString *string);                                 //将字符串string按照指令来执行
    23 
    24 //增[尾部增加](字符/字符串):
    25 void backAddChar(myString *string,char ch);                 //尾部增加字符
    26 void backAddStr(myString *string,char *str);                //尾部增加字符串
    27 
    28 //查(字符/字符串):
    29 char *findFirstChar(myString *string, char ch);    //在字符串string中查找第一个出现的字符ch,返回第一个找到的字符
    30 char *findFirstStr(myString *string, char *str);   //在字符串string中查找第一个子串str,返回第一个找到的子串的地址
    31 
    32 //删(字符/字符串)
    33 int delFirstChar(myString *string, const char ch);          //成功返回0,失败返回-1;依赖于查找函数;删除第一个找到的字符
    34 int delFirstStr(myString *string, char * const str);        //删除第一个找到的字符串
    35 
    36 //增[任意位置增加](字符/字符串):
    37 void addChar(myString *string, char ch, char *pos);     //任意位置增加字符
    38 void addStr(myString *string, char *str, char *pos);    //任意位置增加字符串
    39 
    40 //改(字符/字符串)
    41 void changeFirstChar(myString *string, const char oldChar, const char newChar);     //修改字符
    42 void changeFirstStr(myString *string, char * const oldStr, char * const newStr);    //修改字符串

    myString.c 代码如下:

      1 #define _CRT_SECURE_NO_WARNINGS
      2 #include <stdlib.h>
      3 #include <string.h>
      4 #include <stdio.h>
      5 #include "myString.h"
      6 
      7 //实现库函数strlen():
      8 int mystrlen(const char *p)
      9 {
     10     if (p == NULL)
     11         return -1;        //失败
     12     int len = 0;
     13     while (*p != '')    //字符串终止条件
     14     {
     15         len++;            //长度自增
     16         p++;              //指针不断向前
     17     }
     18     return len;
     19 }
     20 
     21 //实现库函数strcpy():
     22 char *mystrcpy(char *strDest, const char *strSrc)    //const限定不被意外修改
     23 {
     24     if (strDest == NULL || strSrc == NULL)           //异常处理
     25         return NULL;
     26 
     27     char *destbak = strDest;    //destbak保留strDest的初始位置,因为循环结束后strDest指向了末尾
     28     while (*strSrc != '')
     29     {
     30         *strDest = *strSrc;     //赋值字符
     31         strSrc++;
     32         strDest++;              //指针不断向前,字符挨个赋值
     33     }
     34     *strDest = '';            //注意:此处需要添加''作为结束
     35     return destbak;             //返回的是strDest的起始位置,所以用destbak
     36 }
     37 
     38 //初始化结构体字符串
     39 void init(myString *string)
     40 {
     41     string->p = NULL;
     42     string->realLen = 0;
     43 }
     44 
     45 void initWithLen(myString *string, int len)
     46 {
     47     //string->p = (char *)malloc(sizeof(char *)*len);    //分配内存,但是分配的内存不为‘0’,可以使用calloc函数
     48     string->p = (char *)calloc(len, sizeof(char *));     //分配内存并清0,避免了垃圾数据的影响
     49     string->realLen = len;                               //长度
     50 }
     51 
     52 void initWithString(myString *string, char *copyString)
     53 {
     54     int length = mystrlen(copyString);                      //获取字符串长度,需实现strlen()库函数
     55     string->p = (char *)calloc(length + 1, sizeof(char));   //分配内存
     56     mystrcpy(string->p, copyString);                        //拷贝字符串,需实现strcpy()库函数
     57     string->realLen = length + 1;                           //设置长度
     58 }
     59 
     60 //打印字符串
     61 void printString(myString *string)
     62 {
     63     printf("%s
    ", string->p);
     64 }
     65 
     66 void run(myString *string)
     67 {
     68     system(string->p);        //执行指令
     69 }
     70 
     71 //-----------------------------------增[尾部增加](字符/字符串)-------------------------------------------------
     72 //实现库函数strcat():
     73 char *mystrcat(char *strDest, const char *strSrc)
     74 {
     75     if (strDest == NULL || strSrc == NULL)    
     76         return NULL;          //失败
     77     
     78     char *destbak = strDest;
     79     while (*strDest != '')
     80     {
     81         strDest++;            //strDest指针向前移动,一直到最后一个字符''的位置
     82     }
     83     while (*strSrc != '')   //从strDest尾部开始拷贝
     84     {
     85         *strDest = *strSrc;
     86         strSrc++;
     87         strDest++;
     88     }
     89     *strDest = '';
     90     return destbak;
     91 }
     92 
     93 //尾部增加字符
     94 void backAddChar(myString *string, char ch)
     95 {
     96     if (mystrlen(string->p) + 1 == string->realLen)    //意味着满了
     97     {
     98         //重新分配内存,增加一个字符的位置
     99         string->p = realloc(string->p, string->realLen + 1);
    100         string->realLen += 1;        //注意:不能用 string->realLen++; 若用++,这个值在寄存器中而并没有赋值
    101 
    102         string->p[string->realLen - 2] = ch;
    103         string->p[string->realLen - 1] = '';
    104     }
    105     else
    106     {
    107         int nowLen = mystrlen(string->p);    //求出当前长度
    108         string->p[nowLen] = ch;
    109         string->p[nowLen + 1] = '';        //字符增加
    110     }
    111 }
    112 
    113 //尾部增加字符串
    114 void backAddStr(myString *string, char *str)
    115 {
    116     int nowStrLen = mystrlen(string->p);           //获取当前字符串长度
    117     int addStrLen = mystrlen(str);                  //要增加的字符串的长度
    118     if (nowStrLen + addStrLen + 1 > string->realLen)    //判定是否越界
    119     {
    120         int needAddLen = nowStrLen + addStrLen + 1 - string->realLen;            //需要扩展的长度
    121         string->p = (char *)realloc(string->p, string->realLen + needAddLen);    //增加字符串长度
    122 
    123         mystrcat(string->p, str);            //拷贝字符串,需要自己实现库函数strcat()
    124         string->realLen += needAddLen;       //增加长度
    125     }
    126     else
    127     {
    128         mystrcat(string->p, str);            //拷贝字符串
    129     }
    130 }
    131 
    132 //-----------------------------------查(字符/字符串)-------------------------------------------------
    133 //在字符串string中查找第一个出现的字符ch,返回第一个找到的字符
    134 //实现库函数strchr():在字符串string中查找第一个出现的字符ch
    135 //函数原型:  char *strchr(char *str,char c);
    136 char *mystrchr(const char *str, const char c)
    137 {
    138     if (str == NULL)        //异常情况
    139         return NULL;
    140 
    141     while (*str != '')
    142     {
    143         if (*str == c)
    144         {
    145             return str;     //找到返回地址
    146         }
    147         str++;
    148     }
    149     return NULL;            //没有找到返回NULL
    150 }
    151 char *findFirstChar(myString *string, char ch)
    152 {
    153     char *p = mystrchr(string->p, ch);
    154     return p;
    155 }
    156 //在字符串string中查找第一个子串str,返回第一个找到的子串的地址
    157 //实现库函数strstr():在字符串str1中查找指定子串str2,返回第一个找到的子串的地址
    158 //函数原型:  char *strstr(char *str1,char *str2);
    159 char *mystrstr(const char * const str1, const char * const str2)    //注意这里第二个const的使用,不允许str1指针后移
    160 {
    161     if (str1 == NULL || str2 == NULL)  //异常
    162         return NULL;
    163 
    164     char *p = NULL;                    //保存找到的地址
    165     char *strbak1 = str1;              //对str1的起始位置作备份
    166     
    167     while (*strbak1 != '')
    168     {
    169         int flag = 1;                //标识符,一开始假定是相等的
    170         char *strbak2 = str2;        //此语句放在循环中,每次循环都需要重新赋值
    171         char *nowstrbak1 = strbak1;
    172 
    173         while (*strbak2 != '')
    174         {
    175             if (*nowstrbak1 != '')        //没有到str1的末尾
    176             {
    177                 if (*strbak2 != *nowstrbak1)//有一个不等
    178                 {
    179                     flag = 0;    //赋值为0,代表不等
    180                 }
    181                 nowstrbak1++;
    182                 strbak2++;
    183             }
    184             else
    185             { 
    186                 flag = 0;
    187                 break;
    188             }
    189         }
    190 
    191         if (flag == 1)
    192         {
    193             p = strbak1;    //当前位置
    194             return p;
    195         }
    196         strbak1++;
    197     }
    198     
    199     return NULL;
    200 }
    201 char *findFirstStr(myString *string, char *str) 
    202 {
    203     char *pres = mystrstr(string->p, str);
    204     return pres;        //返回地址
    205 }
    206 
    207 //-----------------------------------删(字符/字符串)-------------------------------------------------
    208 //删除第一个找到的字符
    209 int delFirstChar(myString *string, const char ch)    //成功返回0,失败返回-1;依赖于查找函数
    210 {
    211     char *p = mystrchr(string->p, ch);        //查找
    212     
    213     if (p == NULL)
    214         return 0;
    215     else
    216     {
    217         char *pnext = p + 1;
    218         while (*pnext != '')
    219         {
    220             *p = *pnext;     //删除一个字符,整体向前移动
    221             p++;
    222             pnext++;
    223         }
    224         *p = '';            //字符串一定要有结尾
    225 
    226         return 1;
    227     }
    228 }
    229 
    230 //删除第一个找到的字符串
    231 int delFirstStr(myString *string, char * const str)
    232 {
    233     char *p = mystrstr(string->p, str);    //查找
    234 
    235     if (p == NULL)
    236         return 0;
    237     else
    238     {
    239         int length = mystrlen(str);        //求子串的长度
    240         char *pnext = p + length;
    241         while (*pnext != '')
    242         {
    243             *p = *pnext;    //删除一个字符,整体向前移动
    244             p++;
    245             pnext++;
    246         }
    247         *p = '';
    248 
    249         return 1;
    250     }
    251 }
    252 
    253 //-----------------------------------增[任意位置增加](字符/字符串)-------------------------------------------------
    254 //任意位置增加字符
    255 void addChar(myString *string, char ch, char *pos)
    256 {
    257     if (pos == NULL || string == NULL)    //异常情况
    258         return;
    259 
    260     if (mystrlen(string->p) + 1 == string->realLen)    //意味着满了
    261     {
    262         //重新分配内存,增加一个字符的位置
    263         string->p = realloc(string->p, string->realLen + 1);
    264         string->realLen += 1;        //注意:不能用 string->realLen++; 若用++,这个值在寄存器中而并没有赋值
    265 
    266         int nowLen = mystrlen(string->p);       //求出当前长度
    267         int moveLen = mystrlen(pos);            //求出现在要移动的长度
    268         for (int i = nowLen - 1; i > (nowLen - moveLen); i--)
    269         {
    270             string->p[i] = string->p[i - 1];    //轮询移动
    271         }
    272         string->p[nowLen - moveLen] = ch;       //先移动,再插入
    273 
    274         string->p[nowLen + 1] = '';           //注意结尾
    275     }
    276     else
    277     {
    278         int nowLen = mystrlen(string->p);       //求出当前长度
    279         int moveLen = mystrlen(pos);            //求出现在要移动的长度
    280         for (int i = nowLen - 1; i > (nowLen - moveLen); i--)
    281         {
    282             string->p[i] = string->p[i - 1];    //轮询移动
    283         }
    284         string->p[nowLen - moveLen] = ch;       //先移动,再插入
    285         
    286         string->p[nowLen + 1] = '';           //注意结尾
    287     }
    288 }
    289 
    290 //任意位置增加字符串
    291 void addStr(myString *string, char *str, char *pos)
    292 {
    293     if (pos == NULL || string == NULL)      //异常情况
    294         return;
    295 
    296     int nowStrLen = mystrlen(string->p);    //获取当前字符串长度
    297     int addStrLen = mystrlen(str);          //要增加的字符串的长度
    298     if (nowStrLen + addStrLen + 1 > string->realLen)    //判定是否越界
    299     {
    300         int needAddLen = nowStrLen + addStrLen + 1 - string->realLen;            //需要扩展的长度
    301         string->p = (char *)realloc(string->p, string->realLen + needAddLen);    //增加字符串长度
    302         string->realLen += needAddLen;                 //增加长度
    303 
    304         //移动,拷贝
    305         int nowStrLen = mystrlen(string->p);     //获取当前字符串长度
    306         int moveStrLen = mystrlen(pos);          //求出现在要移动的长度
    307         int insertStrLen = mystrlen(str);        //要插入的长度
    308 
    309         for (int i = nowStrLen; i >= nowStrLen - moveStrLen; i--)
    310         {
    311             string->p[i + insertStrLen] = string->p[i];        //字符移动
    312         }
    313         for (int j = 0; j < insertStrLen; j++)
    314         {
    315             string->p[nowStrLen - moveStrLen + j] = str[j];    //赋值拷贝
    316         }
    317     }
    318     else
    319     {
    320         mystrcat(string->p, str);            //拷贝字符串
    321     }
    322 }
    323 
    324 //-----------------------------------//改(字符/字符串)-------------------------------------------------
    325 //修改字符
    326 void changeFirstChar(myString *string, const char oldChar, const char newChar)
    327 {
    328     char *pstr = string->p;
    329     while (*pstr != '')
    330     {
    331         if (*pstr == oldChar)   //查找
    332         {
    333             *pstr = newChar;    //赋值
    334             return;
    335         }
    336         pstr++;
    337     }
    338 }
    339 
    340 //修改字符串
    341 void changeFirstStr(myString *string, char * const oldStr, char * const newStr)
    342 {
    343     char *pfind = findFirstStr(string, oldStr); //找到位置
    344     if (pfind != NULL)
    345     {
    346         delFirstStr(string, oldStr);            //删除
    347         addStr(string, newStr, pfind);          //插入
    348     }
    349 }
    350 
    351 
    352 void main()
    353 {
    354     myString str1;
    355     initWithString(&str1,"note");
    356 
    357     printString(&str1);                            //note
    358     
    359     /* 测试一:****************************************************************/
    360     //backAddChar(&str1, 'd');
    361     //printString(&str1);                        //noted
    362     //run(&str1);
    363 
    364     //backAddStr(&str1, "pad");
    365     //printString(&str1);                        //notepad
    366     //run(&str1);
    367 
    368     /* 测试二:****************************************************************/
    369     //backAddStr(&str1, "pad");
    370     //printString(&str1);                        //notepad
    371     //char *strp = findFirstChar(&str1, 'a');
    372     //*strp = 'A';
    373     //printString(&str1);                        //notepAd
    374 
    375     //backAddStr(&str1, "pad");
    376     //printString(&str1);                        //notepad
    377     //char *strp = findFirstStr(&str1, "te");
    378     //*strp = 'X';
    379     //printString(&str1);                        //noXepad
    380 
    381     //backAddStr(&str1, "pad");
    382     //printString(&str1);                        //notepad
    383     //char *strp = findFirstStr(&str1, "ad");
    384     //*strp = 'X';
    385     //printString(&str1);                        //notepXd
    386 
    387     //backAddStr(&str1, "pad");
    388     //printString(&str1);                        //notepad
    389     //char *strp = findFirstStr(&str1, "ada");
    390     //if (strp != NULL)
    391     //{
    392     //    *strp = 'X';
    393     //}
    394     //printString(&str1);                        //notepad(并没有改变,没有找到相应子串)
    395 
    396     /* 测试三:****************************************************************/
    397     //backAddStr(&str1, "pad");                    
    398     //printString(&str1);                        //notepad
    399     //delFirstChar(&str1,'e');
    400     //printString(&str1);                        //notpad
    401 
    402     //backAddStr(&str1, "padnotepad");
    403     //printString(&str1);                        //notepadnotepad
    404     //delFirstStr(&str1, "pad");
    405     //printString(&str1);                        //notenotepad
    406 
    407     /* 测试四:****************************************************************/
    408     //backAddStr(&str1, "padnotepad");
    409     //printString(&str1);                        //notepadnotepad
    410     //char *p = findFirstChar(&str1, 't');//查找第一个t的位置
    411     //if (p != NULL)
    412     //{
    413     //    addChar(&str1, 'A', p);            //在p的前面位置插入'A'
    414     //}
    415     //printString(&str1);                        //noAtenotepa
    416 
    417     //backAddStr(&str1, "padnotepad");
    418     //printString(&str1);                        //notepadnotepad
    419     //char *p = findFirstChar(&str1, 't');//查找第一个t的位置
    420     //if (p != NULL)
    421     //{
    422     //    addStr(&str1, "12345", p);            //在p的前面位置插入'A'
    423     //}
    424     //printString(&str1);                        //no12345tepadnotepad
    425 
    426     /* 测试五:****************************************************************/
    427     //backAddStr(&str1, "padnotepad");
    428     //printString(&str1);                        //notepadnotepad
    429     //changeFirstChar(&str1, 'a', 'i');
    430     //printString(&str1);                        //notepidnotepad
    431 
    432     backAddStr(&str1, "padnotepad");
    433     printString(&str1);                        //notepadnotepad
    434     changeFirstStr(&str1, "notepad", "123456789");
    435     printString(&str1);                        //123456789notepad
    436 
    437     system("pause");
    438     return ;
    439 }
    文章写来不易,转载请标注。。。欢迎关注!
  • 相关阅读:
    MySQL优化---主从复制
    MySQL性能优化---优化方案
    MySQL性能优化---索引
    MySQL性能优化---定位慢查询
    Linux开机启动过程详解
    naginx
    Git搭建
    脚本中特殊字符
    Shell脚本
    简单Shell脚本(实例)
  • 原文地址:https://www.cnblogs.com/si-lei/p/9458768.html
Copyright © 2011-2022 走看看