C语言:字符函数和字符串函数

一, 字符分类函数

C语⾔中有⼀系列的函数是专⻔做字符分类的,也就是⼀个字符是属于什么类型的字符的。 这些函数的使⽤都需要包含⼀个头⽂件是 ctype.h

1,iscntrl函数

原型:

int iscntrl(int c );

这里的参数int c可以理解为对应字符的ASCII码值。

功能:检查参数c是否为需要一个控制字符(ASCII码值在0~31之间的,包括DEL字符)

附:ASCII码值表

返回值:如果是控制字符,返回值不为0,否则返回值为0.

 实操:

2,isspace函数

原型:

int isspace(int c);

功能:检查参数c是否为空白字符(空白字符的定义如上图所示)

返回值:如果c是空白字符,则返回值不为0,否则为0;

实操:

3,isdigit函数

原型:

int isdigit(int c);

功能:检查参数c是否为十进制数字(0,1,2,3,4,5,6,7,8,9)

返回值:如果是,返回值不为0,否则为0。

4,isxdigit函数

原型:

int isxdigit(int c);

功能:检查参数c是否为十六进制数字字符(0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f,A,B,C,D,E,F)

返回值:如果参数c是十六进制数字,则该返回值不为0,否则为0.

实操:

5,islower函数

原型:

int islower(int c);

功能:检查参数c是否为小写字母。

返回值:如果参数c是小写字母,则该返回值不为0,否则为0。

6,isupper函数

与islower同理。

7,isalpha函数

原型:

int isalpha(int c);

功能:检查参数c是否为字母(a~z,A~Z)

返回值:如果c确实是字母,则返回值不为0,否则为0 。

实操:

8,isalnum函数

原型:

int isalnum(int c);

 功能:检查参数c是否为十进制数字还是大写或者小写字母。

返回值:如果c确实是数字或者字母,则该返回值不为0,否则为0.

实操:

9,ispunct函数

原型:

int ispunct(int c);

功能:检查参数c是否为一个符号(问号,逗号等)。

返回值:如果参数c是一个符号,则返回非0值,否则返回0。

实操:

10,isgraph函数

原型:

int isgraph(int c);

功能:检查字符是否有图形表示(除空格字符以外所有可以打印的字符)

返回值:如果c具有字符的图形表示,则该值不为0,否则该值为0。

实操:

11,isprint函数

原型:

int  isprint(int c);

功能:检查字符c是否为可打印的字符(在显示器上占据显示位置的字符)

返回值:如果c确实是可打印的字符,则返回值不为0,否则为0。

实操:

练习:将字符串中的代码大写转小写

思路1:利用字母大写ASCII码值=小写字母ASCII码值-32.

优化:当一个字符串中既有大写字母又有小写字母时,可以借用字符分类函数进行优化。

思路2:借用字符转换函数。

二,字符转换函数

1,tolower函数

原型:

int tolower(int c);

功能:将参数c由大写字母转换为小写字母

返回值:大写字母返回对应的小写字母,小写字母不做更改返回。

2,toupper函数

原型:

int toupper(int c);

功能:将小写字母转换为大写字母

返回值:大写字母不做更改返回,小写字母返回对应的小写字母

3,大写转小写字符串的优化

三,strlen函数

原型:

size_t strlen(const char*c);

注意:• 字符串以 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前⾯出现的字符个数(不包'\0') 。

• 参数指向的字符串必须要以 '\0' 结束。

• 注意函数的返回值为size_t,是⽆符号的(易错)

补充:size_t类型

size_t类型 无符号数整数类型
1,与编译器相关的无符号整数的c/c++类型
2,类型大小可选择,通常下足以保证存储内存中对象的大小  在不同平台和编译器下下大小可以不同
3,用于数组索引,在循环中遍历数组或者容器的元素,可以保证足够大以表示数组的索引范围,从而避免溢出问题
4,用于内存分配,表示内存分配的大小,有助于确保分配足够的内存以容纳数据

• strlen的使⽤需要包含头⽂件<string.h>

实操:

模拟实现:

1,计数器方式

int my_strlen(const char * str)
 {
   int count = 0;//借用临时变量count来纪录循环次数,当做字符串长度
   assert(str);
   while(*str)//当字符串为0是终止循环
   {
     count++;
     str++;
   }
   return count;
 }

2,递归法

int my_strlen(const char * str)
 {
   assert(str);
   if(*str == '\0')
   return 0;
   else
   return 1+my_strlen(str+1);//借用函数递归实现,最后返回值即为字符串长度
 }

3,指针法

int my_strlen(char *s)
 {
   assert(str);
   char *p = s;//借用p存放字符串首元素地址
   while(*p != '\0' )
   p++;
   return p-s;//通过指针-指针计算字符串长度
 }

补充:指针-指针计算的是两个指针之间的距离(可正可负)  两个指针必须都指向同一块连续的空间。

四,strcpy函数

原型:

char* strcpy(char* destination, const char* source);

功能:将source的字符串复制到destination中

注意:

返回值:返回destination字符串首元素的地址

实操:

模拟实现:
思路:采用循环将字符串逐一拷贝直到拷贝完源头字符串的结束标志'\0"为止
注意事项:

1因为最后需要返回目的地的起始地址,因此拷贝前应当提点记录下目的地起始位置的指针
2,因为无论源地址为NULL,还是目的地地址为NULL,在后续函数的运行过程中都会导致指针的越界访问,因此我们选择在函数一开始就加入assert断言,防止传入空指针情况的出现
3,我们循环终止的条件是(源字符串不等于'\\0'),这意味着当函数拷贝到'\\0'字符时就会停止拷贝,结束运行,这会导致'\\0'并没有被拷贝到目的地中,后续可能会导致出现一些Bug.因此我们应该在循环结束后再将'\\0'也拷贝到目的地中,防止程序出现问题.

char* Mycpy(char* dest, char* sour,int sz)
{
	assert(dest);
	assert(sour);
	char* p1 = dest;
	for (int i = 0; i < sz; i++)
	{
		*(dest + i) = *(sour + i);
		if (*sour = '\0')
			break;
	}
	return p1;
}
int main()
{
	char arr1[40] = { 0 };
	char arr2[] = "Manchester United";
	int sz = strlen(arr2);
	Mycpy(arr1, arr2, sz);
	printf("%s\n", arr1);
}

五,strcat函数

原型:

char*strcat(char*destination,const char*source);

功能:将source字符串追加到destination后面,会将dest中‘\0’覆盖。

注意:1, 源字符串必须以 '\0' 结束。

•2,⽬标字符串中也得有 \0 ,否则没办法知道追加从哪⾥开始。

•3,⽬标空间必须有⾜够的⼤,能容纳下源字符串的内容。

• 4,⽬标空间必须可修改。

5,字符串不能自己给自己追加(‘\0’被覆盖,没有终止条件)。

返回值:同strcpy。

实操:

模拟实现:

char* My_cat(char* p1, const char* p2)
{
	assert(p1);//断言,p1不为空指针,否则会报错
	assert(p2);//断言,p2不为控制着,否则会报错
	char* tmp = p1;//保存p1指针的位置,以保证能找到p1所在位置
	while (*p1)
	{
		p1++;//遍历p1字符串到'\0',使得此时p1指针指向终止字符的位置
	}
	while((*p1++ = *p2++))//将p2字符串的内容逐个字符的复制到p1中
	{
		;
	}
	return tmp;
}

六,strcmp函数

返回值:

标准规定:

1 第⼀个字符串⼤于第⼆个字符串,则返回⼤于0的数字

2 第⼀个字符串等于第⼆个字符串,则返回0

3 第⼀个字符串⼩于第⼆个字符串,则返回⼩于0的数字

4 那么如何判断两个字符串?⽐较两个字符串中对应位置上字符ASCII码值的⼤⼩

实操:

模拟实现:

 int my_strcmp (const char * str1, const char * str2)
 {
   int ret = 0 ;
   assert(str1 != NULL);
   assert(str2 != NULL);
   while(*str1 == *str2)//比较字符串
   {
     if(*str1 == '\0')//当字符串长度相等时,最后str就为终止符,证明比较完毕
        return 0;
     str1++;
     str2++;//保证两个字符串都是逐个字符比较
   }
     return *str1-*str2;//最后返回值的实现就是对应ASCII码值的差值
 }

七,strncpy函数

1,拷⻉num个字符从源字符串到⽬标空间。

2, 如果源字符串的⻓度⼩于num,则拷⻉完源字符串之后,在⽬标的后边追加0,直到num个。

这里不再展示实操和,同理于strcpy。

模拟实现:

八,strncat函数

• Appendsthefirstnumcharactersofsourcetodestination, plus a terminating null-character. (将source指向字符串的前num个字符追加到destination指向的字符串末尾,再追加⼀个 '\0'字符)

• IfthelengthoftheCstringinsourceis less than num,onlythecontentuptotheterminating null-character is copied.(如果source 指向的字符串的⻓度⼩于num的时候,只会将字符串中到 \0 的内容追加到destination指向的字符串末尾)。

实操:

模拟实现(可以通过count来控制循环次数)

九,strncmp函数

比较的两者的ASCII码值

十,strstr函数

注意:c中和c++中对于strstr的声明不同。

1,返回的是str1字符串中匹配到的位置,因此可通过指针偏移量得到具体位置

int main()
{
	char str1[] = "hello world!";
	char str2[] = "world!";
	char* ret = strstr(str1, str2);
	if (ret == NULL)
		printf("找不到!\n");
	else
	    printf("%d\n", ret - str1);
 
	return 0;
}

2,如果需要查找字符串的最后一次出现,可以使用strstr函数

3,两个字符串都应该是以'\0' 结尾的字符串

实操:

模拟实现:

情况1:

char* My_str(const char* str1, const char* str2)
{
	assert(str1&&str2);//断言 判空
    const char*s1=str1;//定义s1和s2指针去做移动
    const char*s2=str2;
    const char*p=str1;//p指针记录str1的位置
    while(*p)//开始循环
    {
       s1=p;//每次更新起始位置s1
       s2=str2;//每次更新s2的起始位置
       while(s1!='\0"&&s2!='\0'&&*s1==*s2)//s1和s2不为终止符,且s1==s2时,开始循环
       {
           s1++;
           s2++;
       }//1,当s2为0的时候跳出循环 证明寻找完毕,返回当前p(子字符串位置) 2,当两者不相同时跳出循环,此时p++再重新循环判断'\0' ,若还没有碰到主串末尾的话,就要更新s1和s2位置
       if(*s2=='\0')
       {
          return p;
       }
       p++;
    }
   return NULL;

 
}

十一,strtok函数

• sep参数指向⼀个字符串,定义了⽤作分隔符的字符集合 

• 第⼀个参数指定⼀个字符串,它包含了0个或者多个由sep字符串中⼀个或者多个分隔符分割的标 记。

• strtok函数找到str中的下⼀个标记,并将其⽤ \0 结尾,返回⼀个指向这个标记的指针。(注: strtok函数会改变被操作的字符串,所以被strtok函数切分的字符串⼀般都是临时拷⻉的内容并且 可修改。) 

• strtok函数的第⼀个参数不为 中的位置。 NULL ,函数将找到str中第⼀个标记,strtok函数将保存它在字符串

• strtok函数的第⼀个参数为 NULL ,函数将在同⼀个字符串中被保存的位置开始,查找下⼀个标 记。

• 如果字符串中不存在更多的标记,则返回 NULL 指针

实操:

 int main()
 {
 char arr[] = "192.168.6.111";
 char* sep = ".";
 char* str = NULL;
 for (str = strtok(arr, sep); str != NULL; str = strtok(NULL, sep))
 {
 printf("%s\n", str);
 }
 return 0;
 }

十二,strerror函数

strerror 函数可以把参数部分错误码对应的错误信息的字符串地址返回来。 在不同的系统和C语⾔标准库的实现中都规定了⼀些错误码,⼀般是放在 errno.h 这个头⽂件中说明 的,C语⾔程序启动的时候就会使⽤⼀个全局的变量errno来记录程序的当前错误码,只不过程序启动 的时候errno是0,表⽰没有错误,当我们在使⽤标准库中的函数的时候发⽣了某种错误,就会将对应 的错误码,存放在errno中,⽽⼀个错误码的数字是整数很难理解是什么意思,所以每⼀个错误码都 是有对应的错误信息的。strerror函数就可以将错误对应的错误信息字符串的地址返回。

实操:打印几个错误信息

也可以了解⼀下perror函数,perror函数相当于⼀次将上述代码中的第9⾏完成了,直接将错误信息 打印出来。perror函数打印完参数部分的字符串后,再打印⼀个冒号和⼀个空格,再打印错误信息。

补充:perror函数

上述作为学习笔记,其中由转载和借鉴,如有冲突,请与本人联系。

有错误可以在评论区指出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值