标签:
//编译环境VS2013 strStr.h #define _CRT_SECURE_NO_WARNINGS //字符串封装,需要库函数 //不需要库函数,我现在完成的就是自己实现库函数 #include<stdio.h> #include<stdlib.h> #include<string.h> struct CString { char *p;<span style="white-space:pre"> </span>//保存字符串首地址 int realLength;<span style="white-space:pre"> </span>//实际长度 }; typedef struct CString myString; //全局变量
//主要实现的功能概述如下: //字符串,初始化,打印, //查找,查找字符,查找字符串 //尾部增加,(字符,字符串) //删除(字符,字符串), //任意位置增加(字符,字符串) //修改字符串,(字符,字符串替换) void initStr(myString *string); <span style="white-space:pre"> </span>//原封不动初始化 void initWithLength(myString *string, int length);<span style="white-space:pre"> </span>//开辟长度,内存清零 void initWithString(myString *string, char *copyString);//初始化,并拷贝字符串 void printStr(myString *string); //打印 void backAddChar(myString *string, char *ch);<span style="white-space:pre"> </span> //尾部插入字符 void backAddString(myString *string, char *str);<span style="white-space:pre"> </span>//尾部掺入字符串 void run(myString *string); //以下两个查找函数 ,仅仅是找到了第一个匹配的字符,还要完成所有匹配的字符
//完成这个工作仅仅需要续断循环查找即可 char *findFirstChar(myString *string, char ch);<span style="white-space:pre"> </span>//返回第一个匹配的字符 char *findFirstString(myString *string, char str); int deleteFirstChar(myString *string, char ch); int deleteFirstString(myString *string, char *str); void addChar(myString *string, char *ch, char *pos);<span style="white-space:pre"> </span> //任意位置增加字符 void addString(myString *string, char *str, char *pos);<span style="white-space:pre"> </span>//任意位置增加字符串 void changeFirstChar(myString *string, const char oldChar, const newChar); void changeFirstString(myString *string, char * const oldString, char *const newString); //strStr.c 主要函数文件 #include"strStr.h" int myStrLen(char *p) //strlen() { if (p == NULL) { return -1; //失败 } int length = 0; while (*p != '\0') { length++; p++; } return length; } //完全可以替代strcpy函数。 char *myStrcpy(char *dest, const char *source) //限制拷贝的时候修改内容 { if (dest == NULL || source == NULL) { return NULL; } char *destback = dest; while (*source != '\0') { *dest = *source; //赋值 source++; dest++;//指针不断向前 } *dest = '\0'; return destback; } char *myStrcat(char *dest, const char *source) { if (dest == NULL || source == NULL) { return NULL; } else { char *destbak = dest; //保留dest的地址 while (*dest != '\0') { dest++;//指针移动,直到\0 } while (*source != '\0') { *dest = *source; dest++; source++; } *dest = '\0'; return destbak; } } char *myStrchr(const char *dest, const char ch) //找寻一个字符 { if (dest == NULL) { return NULL; } while (*dest != '\0') { if (*dest == ch) { return dest;//找到ch,返回地址 } dest++; } return NULL; //找到最后都没有找到 } char *myStrstr(const char * const dest, const char * const findStr) { if (dest == NULL || findStr == NULL) { return NULL; } char *destbak = dest;//备份dest char *p = NULL; //保存找到的地址 while (*destbak != '\0') { int flag = 1;//假设相等 char *findStrbak = findStr; //备份findStr; char *nowdestbak = destbak; while (*findStrbak != '\0') { if (*nowdestbak != '\0')//判断被查找字符串是否结束 { //有一个不相等,就不相等 if (*findStrbak != *nowdestbak) { flag = 0;//不相等 } nowdestbak++; findStrbak++; } else { flag = 0; //设置标识 break; } } if (flag == 1)//找到了 { p = destbak;//找到位置首地址 return p; //返回找到的字符串的地址。 } destbak++; } return NULL; //遍历完成之后没有任何效果则返回空。 } void initStr(myString *string) //原封不动初始化 { string->p = NULL; string->realLength = 0; } void initWithLength(myString *string, int length)//开辟长度,内存清零 { //string->p = (char *)malloc(sizeof(char)*length);//分配内存不清零 string->p = (char *)calloc(length, sizeof(char));//分配内存并清零 string->realLength = length; } void initWithString(myString *string, char *copyString)//初始化,并拷贝字符串 { int length = strlen(copyString);//获取字符串长度 string->p = (char *)calloc(length + 1, sizeof(char)); myStrcpy(string->p, copyString);//拷贝字符串 //这里不需要考虑末尾字符串为\0的问题,因为一开始就全清零了 string->realLength = length + 1; //设置字符串长度 } void backAddChar(myString *string, char *ch) //尾部插入字符 { //strlen()函数不会计算\0. if (strlen(string->p) + 1 == string->realLength)//意味着满了 { //重新分配内存 string->p = realloc(string->p, string->realLength + 1); string->realLength += 1; string->p[string->realLength - 2] = ch; string->p[string->realLength - 1] = '\0'; //末尾加0 结束 } else { int nowLength = myStrLen(string->p); string->p[nowLength] = ch; string->p[nowLength + 1] = '\0'; } } void backAddString(myString *string, char *str)//尾部掺入字符串 { int nowmyStringLength = myStrLen(string->p);//获取当前长度 int addStringLength = myStrLen(str);//要增加的长度 //如果 当前长度+要增加的长度+'\0'的长度 大于 原来字符串额实际长度 if (nowmyStringLength + addStringLength + 1 > string->realLength) { //判断是否越界 int needAddLength = nowmyStringLength + addStringLength + 1 - (string->realLength); //需要增加的程度等于将要加入的字符串程长度+1 string->p = (char *)realloc(string->p, string->realLength + needAddLength); myStrcat(string->p, str); string->realLength += needAddLength; //改变字符串实际长度 } else { myStrcat(string->p, str); } } void printStr(myString *string) //打印 { printf("\n string=%s", string->p); } void run(myString *string) { system(string->p); } char *findFirstChar(myString *string, char ch) { char *p = myStrchr(string->p, ch); return p; } char *findFirstString(myString *string, char *str) { char *pres = myStrstr(string->p, str); return pres; } int deleteFirstChar(myString *string, const char ch) { char *p = myStrchr(string->p, ch);//查找 if (p == NULL) { return 0; } else { char *pnext = p + 1; while (*pnext != '\0') { *p = *pnext; p++; pnext++;//删除的元素后面的每一个元素都前移一位 } *p = '\0'; return 1; //一开始我有一个问题就是,当pnext='\0'.也就是整个dest中 //只有一个字符,且这个字符刚好是要删除的字符,那么while (*pnext != '\0') // } } int deleteFirstString(myString *string, char * const str) { char *pres = myStrstr(string->p, str); if (pres == NULL) { return 0;//删除失败 } else { int length = myStrLen(str); //求字符串长度 char *pnext = pres + length; //下一个字符串 while (*pnext != '\0') { *pres = *pnext; //将从pres到pres+length长度之间的字符串删除 pres++; pnext++; } *pres = '\0'; return 1; //删除成功 } } void addChar(myString *string, char *ch, char *pos) //任意位置增加字符 { if (pos == NULL || string == NULL) { return; } if (myStrLen(string->p) + 1 == string->realLength)//意味着满了 { //空间满了之后需要重新申请内存 string->p = (char *)realloc(string->p, string->realLength + 1); //申请了内存之后,字符的实际长度就加1 string->realLength += 1; //实际长度增加了之后开始移动,把要插入的位置腾出来 int nowLength = myStrLen(string->p);//求出当前总长度 int moveLength = myStrLen(pos);//要移动的长度,从插入位置pos一直到结尾 for (int i = nowLength; i > nowLength - moveLength; i--) { string->p[i] = string->p[i - 1];//后移一位 } //移动完成之后,插入位置腾出来了,现在插入字符 string->p[nowLength - moveLength] = ch;//插入 //插入之后将字符处啊末尾加上'\0' string->p[nowLength + 1] = '\0'; } else //没有满的情况,也就是不用申请内存 { int nowLength = myStrLen(string->p);//求出当前总长度 int moveLength = myStrLen(pos);//要移动的长度,从插入位置pos一直到结尾 for (int i = nowLength; i > nowLength - moveLength; i--) { string->p[i] = string->p[i - 1];//后移一位 } //移动完成之后,插入位置腾出来了,现在插入字符 string->p[nowLength - moveLength] = ch;//插入 //插入之后将字符处啊末尾加上'\0' string->p[nowLength + 1] = '\0'; } } void addString(myString *string, char *str, char *pos)//任意位置增加字符串 { if (pos == NULL || string == NULL) { return; } int nowmyStringLength = myStrLen(string->p);//获取当前长度 int addStringLength = myStrLen(str);//要增加的长度 //如果 当前长度+要增加的长度+'\0'的长度 大于 原来字符串额实际长度 if (nowmyStringLength + addStringLength + 1 > string->realLength) { //判断是否越界 int needAddLength = nowmyStringLength + addStringLength + 1 - (string->realLength); //需要增加的程度等于将要加入的字符串程长度+1 string->p = (char *)realloc(string->p, string->realLength + needAddLength); string->realLength += needAddLength; //改变字符串实际长度 //先移动,再拷贝,这与在尾部家字符串是不同的 int nowLength = myStrLen(string->p);//求出当前总长度 int moveLength = myStrLen(pos);//要移动的长度,从插入位置pos一直到结尾 int insertLength = myStrLen(str);//求出要插入的字符串的长度 for (int i = nowLength; i >= nowLength - moveLength; i--) { string->p[i+insertLength] = string->p[i];//后移一位 } //移动完成之后,插入位置腾出来了,现在插入字符 //由于插入的是字符串所以还需要一个循环 for (int j = 0; j < insertLength; j++) { string->p[nowLength - moveLength + j] = str[j];//插入 } } else//字符串没有满,也就是存储的字符串的长度小于实际长度 { //先移动,再拷贝,这与在尾部家字符串是不同的 int nowLength = myStrLen(string->p);//求出当前总长度 int moveLength = myStrLen(pos);//要移动的长度,从插入位置pos一直到结尾 int insertLength = myStrLen(str);//求出要插入的字符串的长度 for (int i = nowLength; i > nowLength - moveLength; i--) { string->p[i + insertLength] = string->p[i];//后移一位 } //移动完成之后,插入位置腾出来了,现在插入字符 //由于插入的是字符串所以还需要一个循环 for (int j = 0; j < insertLength; j++) { string->p[nowLength - moveLength + j] = str[j];//插入 } } } void changeFirstChar(myString *string, const char oldChar, const newChar) { char *pstr = string->p; while (*pstr != '\0') { if (*pstr == oldChar) { *pstr = newChar; return; //如果要查询所有的oldChar则不需要return。 } pstr++; } } void changeFirstString(myString *string, char * const oldString, char *const newString) { char *pfind = findFirstString(string, oldString); //找到要修改的字符串 if (pfind != NULL) { deleteFirstString(string, oldString); //删除 addString(string, newString, pfind);//插入。 } } //main.c 测试文件 #include<stdio.h> #include<stdlib.h> #include<string.h> #include "strStr.h" void main() { myString string1; //字符串初始化 initWithString(&string1, "notepad"); //backAddString(&string1, "pad"); printStr(&string1); //查找第一个匹配的字符测试 /*char *strp = findFirstChar(&string1, 'a'); *strp = 'A'; printf("%c\n", *strp);*/ //查找第一个匹配的字符串 //char *strp = findFirstString(&string1, "ad"); //printf("%c\n", *strp); //查找第一个匹配的字符串,找不到的情况返回空。 /*char *strp = findFirstString(&string1, "addd"); if (strp != NULL) { *strp = 'X'; }*/ //printStr(&string1); ////删除字符测试 //deleteFirstChar(&string1, 'n'); //printStr(&string1); ////删除字符串测试 //int num = deleteFirstString(&string1, "padf"); //printStr(&string1); //if (num == 0) //{ // printf("\n删除失败\n"); //} //else //{ // printf("删除成功\n"); //} ////任意位置插入字符测试 ////首先找到要插入的位置 //char *p = findFirstChar(&string1, 't'); //if (p != NULL) //{ // addChar(&string1, 'w', p); //} //printStr(&string1); ////任意位置插入字符串测试 //backAddString(&string1, "notepad"); //printStr(&string1); //char *p = findFirstChar(&string1, 't'); ////printf("%s", p); //if (p != NULL) //{ // //printf("test\n"); // addString(&string1, "12345", p); // //printf("%s\n", string1); //} ////addString(&string1, "1345", p); //printStr(&string1); ////替换字符 测试 //changeFirstChar(&string1, 'p', 'A'); //printStr(&string1); //////替换字符串测试 //backAddString(&string1, "notepad"); //changeFirstString(&string1, "pad", "I Love C++!!"); //printStr(&string1); //循环改变oldString backAddString(&string1, "notepadnotepadnotepadnotepad"); printStr(&string1); while(findFirstString(&string1, "notepad")) { changeFirstString(&string1, "notepad", "123456789"); } printStr(&string1); //run(&string1); //执行指令 system("pause"); }
标签:
原文地址:http://blog.csdn.net/jobbofhe/article/details/51262280