C语言【微项目06】—实现python内置字符串函数12个[有字符串切片、split、list等](采用模拟构造函数方式实现)
目录
【TDTX】
将代码中main()函数删除后,可把本代码当作一个字符串处理的函数库使用练习。
CForPyStrMethod.c
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#define close free
char* ts;
int nls;//split()函数分配指针数组的个数记录
char** ls;//split()函数分隔后的多个字符串形成的list列表
typedef struct String
{
char* shead;
int length;
struct String* (*newString)(void);
int (*len)(struct String* p);
char* (*lower)(struct String* p);
void (*tolower)(struct String* p);
char* (*upper)(struct String* p);
void (*toupper)(struct String* p);
bool (*islower)(struct String* p);
bool (*isupper)(struct String* p);
bool (*isprintable)(struct String* p);
char* (*slice)(struct String* p,int start,int end,int step);
bool (*isnumeric)(struct String* p);
bool (*isspace)(struct String* p);
char** (*split)(struct String* p,char sep,int maxsplit);
}String;
int len(String* p);
char* lower(String* p);
char* upper(String* p);
bool islower(String* p);
void tolower(String* p);
bool isupper(String* p);
void toupper(String* p);
bool isprintable(String* p);
char* slice(String* p,int start,int end,int step);
bool isnumeric(String* p);
bool isspace(String* p);
char** split(String* p,char sep,int maxsplit);
String* newString(void)
{
String* sp;
sp = (String*)malloc(sizeof(String));
sp->shead = (char*)malloc(sizeof(char)*100+1);
(sp->shead)[0] = '\0';
sp->length = 0;
ts = (char*)malloc(sizeof(char)+1);
ts[0] = '\0';
sp->newString = newString;
sp->len = len;
sp->lower = lower;
sp->upper = upper;
sp->islower = islower;
sp->tolower = tolower;
sp->isupper = isupper;
sp->toupper = toupper;
sp->isprintable = isprintable;
sp->slice = slice;
sp->isnumeric = isnumeric;
sp->isspace = isspace;
sp->split = split;
return sp;
}//初始化分配一个101字节的字符数组
int len(String* p)
{
return p->length = strlen(p->shead);
}
char* lower(String* p)
{
int i;
close(ts);
ts = (char*)malloc(sizeof(char)*len(p)+1);
ts[0] = '\0';
for(i = 0;i < len(p);i++)
{
if((p->shead)[i] >= 'A' && (p->shead)[i] <= 'Z')
{
ts[i] = (p->shead)[i] + 32;
//printf("%c\n",ts[i]);
}
else
{
ts[i] = (p->shead)[i];
}
}
ts[len(p)] = '\0';
return ts;
}
void tolower(String* p)
{
int i;
for(i = 0;i < len(p);i++)
{
if((p->shead)[i] >= 'A' && (p->shead)[i] <= 'Z')
{
(p->shead)[i] = (p->shead)[i] + 32;
//printf("%c\n",ts[i]);
}
}
return;
}
char* upper(String* p)
{
int i;
close(ts);
ts = (char*)malloc(sizeof(char)*len(p)+1);
ts[0] = '\0';
for(i = 0;i < len(p);i++)
{
if((p->shead)[i] >= 'a' && (p->shead)[i] <= 'z')
{
ts[i] = (p->shead)[i] - 32;
//printf("%c\n",ts[i]);
}
else
{
ts[i] = (p->shead)[i];
}
}
ts[len(p)] = '\0';
return ts;
}
void toupper(String* p)
{
int i;
for(i = 0;i < len(p);i++)
{
if((p->shead)[i] >= 'a' && (p->shead)[i] <= 'z')
{
(p->shead)[i] = (p->shead)[i] - 32;
//printf("%c\n",ts[i]);
}
}
return;
}
bool islower(String* p)
{
int i;
bool existEn = false;
for(i = 0;i < len(p);i++)
{
if((p->shead)[i] >= 'A' && (p->shead)[i] <= 'Z')
{
existEn = true;
break;
}
if((p->shead)[i] >= 'a' && (p->shead)[i] <= 'z')
{
existEn = true;
break;
}
}//检查是否存在英文字母
if(existEn == false)
{
return false;
}
else
{
for(i = 0;i < len(p);i++)
{
if((p->shead)[i] >= 'A' && (p->shead)[i] <= 'Z')
{
return false;
}
}
}
return true;
}
bool isupper(String* p)
{
int i;
bool existEn = false;
for(i = 0;i < len(p);i++)
{
if((p->shead)[i] >= 'A' && (p->shead)[i] <= 'Z')
{
existEn = true;
break;
}
if((p->shead)[i] >= 'a' && (p->shead)[i] <= 'z')
{
existEn = true;
break;
}
}//检查是否存在英文字母
if(existEn == false)
{
return false;
}
else
{
for(i = 0;i < len(p);i++)
{
if((p->shead)[i] >= 'a' && (p->shead)[i] <= 'z')
{
return false;
}
}
}
return true;
}
bool isprintable(String* p)
{
int i;
for(i = 0;i < len(p);i++)
{
if((p->shead)[i] <= 31 && (p->shead)[i] >= 0)
{
printf("不可打印字符ASCII值:%d\n",(p->shead)[i]);
return false;
}
if((p->shead)[i] == 127)
{
return false;
}
}
return true;
}
bool isnumeric(String* p)
{
int i;
bool existEn = false;
for(i = 0;i < len(p);i++)
{
if((p->shead)[i] >= '0' && (p->shead)[i] <= '9')
{
existEn = true;
break;
}
}//检查是否存在数字
if(existEn == false)
{
return false;
}
else
{
for(i = 0;i < len(p);i++)
{
if((p->shead)[i] < 48 || (p->shead)[i] > 57)
{
return false;
}
}
}
return true;
}
bool isspace(String* p)
{
int i;
for(i = 0;i < len(p);i++)
{
if((p->shead)[i] != ' ')
{
return false;
}
}
return true;
}
char* slice(String* p,int start,int end,int step)
{
int i;
int t = 0;
close(ts);
ts = (char*)malloc(sizeof(char)*len(p)+1);
ts[0] = '\0';
if(start >= 0 && end <= len(p) && start <= end && step >= 0)
{
for(i = start;i < end;i = i + step,t++)
{
ts[t] = (p->shead)[i];
}
ts[t] = '\0';
}//正向增前进
else if(start <= len(p) && end >= 0 && start >= end && step < 0)
{
for(i = start;i > end;i = i + step,t++)
{
ts[t] = (p->shead)[i];
}
ts[t] = '\0';
}//负向倒退
else
{
ts[0] = '\0';
}
return ts;
}
char** split(String* p,char sep,int maxsplit)
{
int i;
int sepcount = 0;
int index[len(p)];
int dtt = 0;
int tdt = 0;
int dxx = 0,dyy = 0;
for(i = 0;i < len(p);i++)
{
index[i] = -1;//index数组全赋初始值1
}
for(i = 0;i < len(p);i++)
{
if((p->shead)[i] == sep)
{
index[dtt] = i;//按照顺序检查到分隔符sep就把其在字符串中的位置记录在index数组中(从index数组0位置记录)
//printf("\n已记录分隔符位置%d在index[%d]中\n",i,dtt);
//printf("dt:%d",dtt);
dtt++;
sepcount++;
}
}//检查字符串中有几个分隔符,为后续的分配空间提供参数
if(maxsplit < 0)
{
//printf("\n找到了sepcount:%d个分隔符\n",sepcount);
//char** ls;
ls = (char**)malloc(sizeof(char*)*(sepcount+1));//按照字符串被划分的段数,分配相应数目的字符指针数组的个数,每个指针指向一段malloc分配的空间,存放分隔后的字符串
nls = sepcount+1;
for(i = 0;i < sepcount+1;i++)
{
if(i == 0)
{
ls[i] = (char*)malloc(sizeof(char)*(index[i]-0)+1);
//printf("\nls[%d]:分配了%d字节!\n",i,index[i]-0+1);
ls[i][0] = '\0';
}
else if(i == sepcount)
{
ls[i] = (char*)malloc(sizeof(char)*(len(p)-index[dtt-1]));
//printf("\nls[%d]:分配了%d字节!\n",i,len(p)-index[dtt-1]);
ls[i][0] = '\0';
}
else
{
ls[i] = (char*)malloc(sizeof(char)*(index[i]-index[i-1])+1);
//printf("\nls[%d]:分配了%d字节!\n",i,index[i]-index[i-1]);
ls[i][0] = '\0';
}
}//已经给每段字符串精准分配好空间,下面开始实际分隔操作
for(i = 0;i < len(p);i++)
{
if(i != index[tdt])
{
ls[dxx][dyy++] = (p->shead)[i];
//printf("赋值:%c",(p->shead)[i]);
}
else
{
ls[dxx][dyy] = '\0';
//puts("分隔检查:");
//printf("i:%d,",i);
//puts(ls[dxx]);
tdt++;
dxx++;
dyy = 0;
}
}
ls[dxx][dyy] = '\0';
//puts("分隔检查:");
//printf("i:%d,",i);
//puts(ls[dxx]);
//printf("\n%d\n",sizeof(ls)/sizeof(char*));
return ls;
}
else
{
return NULL;
//不再实现,可由上述情况的实现改编而来
}
}
void putls(char** ls)
{
int i;
printf("[");
for(i = 0;i < nls;i++)
{
if(i == nls-1)
{
printf("\'""%s""\'",ls[i]);
}
else
{
printf("\'""%s""\',",ls[i]);
}
}
printf("]");
return;
}
void finalString()
{
close(ts);
}
void finalsplit()
{
int i;
for(i = 0;i < nls;i++)
{
close(ls[i]);
}
close(ls);
}
int main()
{
String* s = newString();
int f,e,stp;
char ssp;
puts("请输入一个字符串:");
gets(s->shead);
printf("\n输入分隔符:");
fflush(stdin);
scanf("%c",&ssp);
printf("分割后list:");
putls(s->split(s,ssp,-1));
puts("");
printf("\n检查该字符串是否全是空格:%s\n",s->isspace(s)?"true":"false");
printf("检查该字符串是否全是数字:%s\n",s->isnumeric(s)?"true":"false");
printf("\n输入切片起止范围与步长(空格分隔):");
scanf("%d %d %d",&f,&e,&stp);
String* s_slice= newString();
s_slice->shead = s->slice(s,f,e,stp);
puts(s_slice->shead);
printf("\n将该切片分割,输入分隔符:");
fflush(stdin);
scanf("%c",&ssp);
printf("分割后list:");
putls(s->split(s_slice,ssp,-1));
puts("");
printf("检查该字符串是否全是可打印字符:%s\n",s->isprintable(s)?"true":"false");
printf("该字符串英文字母是否全小写:%s\n",s->islower(s)?"true":"false");
printf("该字符串英文字母是否全大写:%s\n",s->isupper(s)?"true":"false");
puts("输出该字符串英文字母全小写和全大写的副本(不改变源字符串):");
puts(s->lower(s));
puts(s->upper(s));
puts("【执行】--将源字符串【英文字母】全变成【小写】!");
s->tolower(s);
printf("该字符串英文字母是否全小写:%s\n",s->islower(s)?"true":"false");
printf("该字符串英文字母是否全大写:%s\n",s->isupper(s)?"true":"false");
puts("【执行】--将源字符串【英文字母】全变成【大写】!");
s->toupper(s);
printf("该字符串英文字母是否全小写:%s\n",s->islower(s)?"true":"false");
printf("该字符串英文字母是否全大写:%s\n",s->isupper(s)?"true":"false");
printf("字符串长度:%d\n",s->len(s));
finalString();//只要调用了lower或upper才可以使用
finalsplit();//只要调用了split才可以使用
return 0;
}
运行结果示例
一、输入一个字符串,分隔符'-',切片方式正向增长(步长为1),分隔该切片,分隔符'o'
输入的字符串是:"hello-world-tom-marry sdda-dsadak -d --"
二、输入一个字符串,分隔符' ',切片方式负向减少(步长为-2),分隔该切片,分隔符'r'
输入的字符串是:"hello-world-tom-marry sdda-dsadak -d --"
------------------------------------------------------第六次发项目类文章有点激动啊!-----------------------------------------------------
-----------------------------------------------------【C语言—微项目—自编练习】------------------------------------------------------
----------------------------------------------------------------【TDTX】-----------------------------------------------------------------