#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
/*
#define SHORTSTRINGLEN 24
#define MIDSTRINGLEN 64
#define LONGSTRINGLEN 256
#define SHORTTEXTLEN 1024
#define LONGTEXTLEN 4096
*/
typedef struct string
{
size_t len;
char *ch;
}Str;
#define INITNULLSTRING(str) ((str)->len=0)
#define ISNULLSTRING(str) ((str)->len==0)
#define STRINGLENGTH(str) ((str)->len)
#define GETSTRING(str,n) (fgets((str)->ch,n,stdin))
#define PUTSTRING(str) (puts((str)->ch))
size_t StringInit(Str* str,char *s)
{
str->len=strlen(s);
//为字符串开辟相应大小的空间
str->ch=(char*)malloc(str->len+1);
if(str->ch==0) exit(1);
//实现字符串的复制
strcpy(str->ch,s);
return str->len;
}
void StringDes(Str *str)
{
//释放str->ch的空间
free(str->ch);
str->len=0;
}
int StringCmp(Str *str1,Str *str2)
{
return strcmp(str1->ch,str2->ch);
}
size_t StringCpy(Str *str1,Str *str2)
{
//比较两个字符的长度,看看是不是要从新分配空间
if(str1->len<str2->len)
{
//从新分配空间要释放掉str1->ch所指向的空间
StringDes(str1);
//从新开辟
str1->ch=(char*)malloc(sizeof(str2->len+1));
if(str1->ch==0) exit(1);
}
strcpy(str1->ch,str2->ch);
return str1->len=str2->len;
}
size_t StringCat(Str *str1,Str *str2)
{
// 开辟大小相应的空间来放这两个字符串
str1->ch=(char*)realloc(str1->ch,strlen(str1->ch)+strlen(str2->ch)+1);
if(str1->ch==0) exit(1);
strcat(str1->ch,str2->ch);
return str1->len += str2->len;
}
char* StringChr(Str *str,char ch)
{
return strchr(str->ch,ch);
}
char* StringRChr(Str* str,char ch)
{
return strrchr(str->ch,ch);
}
char* StringStrR(Str* str,char *p)
{
return strstr(str->ch,p);
}
size_t StringNCmp(Str* str1,Str *str2,int n)
{
return strncmp(str1->ch,str2->ch,n);
}
Str* StringNCpy(Str *str1,Str *str2,int n)
{
int len_str1=strlen(str1->ch);
int len_str2=strlen(str2->ch);
//在这个操作中应该判断一下,str->ch的长度有没有短于str->ch的长度
if(len_str1<len_str2||len_str1<=n)
{
//长度过长后应该从新分配空间,并把原来的空间释放
char *p=str1->ch;
free(p);
str1->ch=(char*)malloc(sizeof(str2->len+1));
if(str1->len==0) exit(1);
}
str1->len=(n<len_str1?n:len_str2);
strncpy(str1->ch,str2->ch,n);
return str1;
}
//去字符串中常见的控制符StringTrim()
size_t StringTrim(Str *str)
{
//用p来记下原来字符串的地址
char *p=str->ch;
int i=0;
//为新串开辟一个足够长的空间
str->ch=(char*)malloc(sizeof(strlen(p)+1));
if(str->ch==0) exit(1);
//把非格式字符复制到新串中去
while(*p)
{
switch(*p)
{
case '/n':
case '/t':
case '/r':
case '/v':
case '/f':
case ' ':
break;
default:
str->ch[i++]=*p;
}
p++;
}
str->ch[i]=0;
//把旧串释放掉
free(p);
return str->len=i;//更新旧串的长度
}
size_t fgetSring(Str *s, int n, FILE *stream)
{
//检查读取的字符串长会不会长过str->len
if(s->len<n)
{//长了之后要从新开辟空间并且要把原来的字符串free掉
free(s->ch);
s->ch=(char*)malloc(n+1);
if(s->ch==0) exit(1);
}
fgets(s->ch,n,stream);
return s->len=strlen(s->ch);
}
size_t fputSring(Str *s, FILE *stream)
{
fputs(s->ch,stream);
return s->len;
}
int isNumberString(Str *str)
{
int i;
for(i=0;i<str->len;i++)
{
if((str->ch)[i]<=48||(str->ch)[i]>=57) return 0;
}
return 1;
}
/*辅助函数*/
int toint(char *str)
{
return (str[0]-'0')*10+str[1]-'1';
}
//假设时间格式为:20:02:10.01
int isDataString(Str *str)
{
//把字符串中的时转成整形
int num=toint(str->ch);
if(num<0||num>=24) return 0;
//然后是不是‘:’
if((str->ch)[2]!=':') return 0;
//把字符串中的分转成整形
num=toint(&((str->ch)[3]));
if(num<0||num>=60) return 0;
//然后是不是‘:’
if((str->ch)[5]!=':') return 0;
//把字符串中的秒转成整形
num=toint(&((str->ch)[6]));
if(num<0||num>=60) return 0;
//然后是不是‘.’
if((str->ch)[8]!='.') return 0;
//把字符串中的毫秒转成整形
num=toint(&((str->ch)[9]));
if(num<0||num>=100) return 0;
return 1;
}
int isCharString(Str *str)
{
int i;
for(i=0;i<str->len;i++)
{
if((str->ch)[i]<41||(str->ch)[i]>122) return 0;
if((str->ch)[i]>=91&&(str->ch)[i]<=96) return 0;
}
return 1;
}
int isPrintString(Str* str)
{
int i;
for(i=0;i<str->len;i++)
{
if((str->ch)[i]<32||(str->ch)[i]>126) return 0;
}
return 1;
}
int isBString(Str *str)
{
int i;
for(i=0;i<str->len;i++)
{
if((str->ch)[i]!='0'&&(str->ch)[i]!='1') return 0;
}
return 1;
}