编程实现串的基本操作:求长度、串的比较、串的连接、取子串、模式匹配等,并完成调用
采用功能菜单表现形式完成功能的调用
程序运行截图:
程序源代码:
/*
environment:Dev-C++
author:monkey-z
time:2019-11-29
*/
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <process.h>
#define OK 1
#define ERROR 1
#define FALSE 0
#define MAXSTRLEN 255 //用户可以在255以内定义最大串长
typedef int Status;
typedef unsigned char SString[MAXSTRLEN+1];//0号单元存放串的长度
using namespace std;
//初始化:0号单元存放串的长度
Status InitStr(SString &S)
{
S[0]=0;
return OK;
}
//生成串
Status StrAssign(SString &S,char chars[])
{
int i;
S[0]=strlen(chars);
for(i=0;chars[i]!='\0'&&i+1<MAXSTRLEN;i++){
S[i+1]=chars[i];
}
S[i+1]='\0';
return OK;
}
//输出串
void PrintStr(SString S)
{
int i;
for(i=1;S[i]!='\0';i++){
cout<<S[i];
}
cout<<endl;
}
//求串长
Status StrLength(SString S)
{
return S[0];
}
//判空
Status StrEmpty(SString S)
{
if(S[0]==0){
return OK;
}
else {
return FALSE;
}
}
//比较字符串
Status StrCompare(SString S,SString T)
{
int i=0;
for(i=0;i<S[0]&&i<T[0];i++){
if(S[i]!=T[i])
return S[i]-T[i];
}
return S[0]-T[0];
}
//字符串连接:用T返回由S1和S2连接成的新串
Status Concat(SString &T,SString S1,SString S2)
{
int i,j;
if(S1[0]+S2[0]<=MAXSTRLEN){
//未超出用户定义的最大串长
for(i=1;S1[i]!='\0';i++){
T[i]=S1[i];
}
for(j=1;S2[j]!='\0';j++){
T[S1[0]+j]=S2[j];
}
//两次循环连接两串
T[S1[0]+j+1]='\0';
T[0]=S1[0]+S2[0];
}
else if(S1[0]<MAXSTRLEN){
//超出用户定义的最大串长,这里会出现截断情况
for(i=1;S1[i]!='\0';i++){
T[i]=S1[i];
}
for(j=1;j<=MAXSTRLEN-S1[0];i++){
T[S1[0]+j]=S2[j];
}
T[0]=MAXSTRLEN;
}
else{
//条件是S1[0]>MAXSTRLEN,这里仅截断S1
for(i=1;S1[i]!='\0';i++){
T[i]=S1[i];
}
T[i+1]='\0';
T[0]=S1[0];
}
return OK;
}
//取子串:用Sub返回串S的第pos个字符起长度为len的子串
//注意:1<=pos<=StrLength(S),0<=len<=StrLength(S)-pos+1
Status SubString(SString &Sub,SString S,int pos,int len)
{
int i,j;
if(pos<1||pos>S[0]||len<0||len>S[0]-pos+1){
return ERROR;
}
for(i=1,j=pos;i<=len&&j<=pos+len-1;i++,j++){
Sub[i]=S[j];
}
Sub[i+1]='\0';
Sub[0]=len;
return OK;
}
//串的模式匹配:返回子串T(非空)在主串中第pos个字符之后的位置。若不存在,则返回0
int Index(SString S,SString T,int pos)
{
int i=pos;
int j=1;
while(i<=S[0]&&j<=T[0]){
if(S[i]==T[j]){
++i;
++j;
}else{
i=i-j+2;
j=1;
}
}
if(j>T[0]){
return i-T[0];
}
else return FALSE;
}
int main(){
SString S1,S2,T,Sub;
int len1,len2,cha,pos,len;
InitStr(T);
InitStr(Sub);
char s1[100];
char s2[100];
cout<<"请输入字符串1:"<<endl;
scanf("%s",s1);
StrAssign(S1,s1);
//PrintStr(S1);
cout<<"请输入字符串2:"<<endl;
scanf("%s",s2);
StrAssign(S2,s2);
cout<<"1.字符串长度 ";
cout<<"2.比较字符串 " ;
cout<<"3.取子串 " ;
cout<<"4.匹配模式 " ;
cout<<"5.连接字符串";
cout<<"6.退出程序"<<endl;
int select;
while(true){
cout<<"请选择你想要的功能;"<<endl;
cin>>select;
switch(select){
case 1:
printf("串1的长度是:%d\n",S1[0]);
printf("串2的长度是:%d\n",S2[0]);
/*
这里有一个很大的问题,我之前写的cout<<S[0]输出串长,发现在dev上输出居然是一个方框的乱码,
害得我以为是我代码出现问题,找了很久问题,最后换成了printf发现居然能输出正常了。
还没搞清楚为什么是这样的表现结果。
*/
break;
case 2:
cha=StrCompare(S1,S2);
cout<<"两串比较的结果是:";
if(cha>0){
cout<<"S1>S2"<<endl;
}else if(cha<0){
cout<<"S1<S2"<<endl;
}else cout<<"S1=S2"<<endl;
break;
case 3:
cout<<"输入你想取的S1的子串具体位置和长度:";
cin>>pos>>len;
if(SubString(Sub,S1,pos,len)){
cout<<"串1的第"<<pos<<"个位置开始长度为"<<len<<"的子串Sub为: ";
PrintStr(Sub);
}else{
cout<<"查找子串失败!"<<endl;
}
break;
case 4:
cout<<"请输入匹配的pos位置:";
cin>>pos;
if(Index(S1,S2,pos)){
cout<<"串2在串1中位置是:"<<Index(S1,S2,pos)<<endl;
}else cout<<"匹配失败!"<<endl;
break;
case 5:
Concat(T,S1,S2);
cout<<"串1和串2连接后的串为:";
PrintStr(T);
break;
case 6:
cout<<"退出程序!";
exit(0);
break;
}
}
}
其他补充的功能:
//删除:删除串S指定的位置开始的长度为len的子串
Status StrDelete(SString &S,int pos,int len){
int i;
if(pos<1||len>S[0]-pos+1){
return ERROR;
}
for(i=pos+len;i<=S[0];i++){
S[i-len]=S[i];
}
S[0]-=len;
return Ok;
}
//清空串
Status ClearString(SString S)
{
int i;
for(i=1;S[i]!='\0';i++){
S[i]='\0';
}
S[0]=0;
return OK;
}
在调试中虽然能得到想要的结果,但是发现关于连接字符串要是超出用户定义的最大长度,不能运行这个功能,逻辑感觉没问题,具体问题出在哪里还需要进一步思考和发现