有关字符串的部分函数

strlen

声明

size_t strlen(const char*str);

函数的返回值为无符号整型
形参为字符串的地址,用const修饰防止修改该地址内的内容
实现

size_t my_strlen(const char* str)
{
	assert(str);//断言防止传参为NULL
	size_t count = 0;
	while (*s++)
	{
		count++;
	}
	return count;
}

使用

#include<stdio.h>
#include<string.h>
int main()
{
	char* c = "abcdef";
	size_t a = strlen(c);
	printf("%zu", a);//6
	return 0;
}

注意
strlen函数在遇到’\0’时停止,结果并不会包括’\0’

strcpy

声明

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

函数的返回值为目标字符串的首地址
形参为字符串的地址,用const修饰防止修改该地址内的内容
实现

char* my_strcpy(char* destination, const char* source)
{
	assert(source);
	char* p = destination;
	while (*destination++ = *source++);
	return p;
}

使用

#include<stdio.h>
#include<string.h>
int main()
{
	char*a="abcdef";
	char b[10]={0};
	char*c=NULL;
	c=strcpy(b,a);
	printf("%s\n",b);//abcdef
	printf("%s\n",c);//abcdef
} 

在这里插入图片描述
注意
strcpy以’\0’为标志,将源地址处第一个’\0’及之前的字符全部复制到目标地址处,但strcpy并不会完全覆盖目标字符串。
请不要复制大于目标字符串的源字符串

strcpy_s

strcpy的升级版,更安全。。。。。。
声明

errno_t strcpy_s(char *strDestination , size_t numberOfElements , const char *strSource);

返回一个整数,0表示复制成功,返回非0值代表复制不成功,不同的值表示不同的错误,具体内容可以查阅MSDN手册。
与strcpy不同的是中间多了一个形参来设置目标缓冲区大小,并非原始缓冲区大小。
实现

errno_t my_strcpy_s(char* strDestination, size_t numberOfElements, const char* strSource)
{
	assert(strSource);
	int count = 1;
	char* p = strDestination;
	while (*strDestination++ = *strSource++)
	{
		if (++count > numberOfElements)
		{
			p[0] = '\0';
			return -1;
		}
	}
	return 0;
}

使用

#include<stdio.h>
#include<string.h>
int main()
{
	char* a = "abcdef";
	char b[10] = { 0 };
	int ret=strcpy_s(b, sizeof(b)/sizeof(b[0]), a);
	//错误写法
	//strcpy_s(b, sizeof(a) / sizeof(a[0]), a);
	printf("%s\n", b);//abcdef
	printf("%d", ret);//0
	return 0;
}

注意
与strcpy一样在遇到’\0’时停止复制,连同’\0’及之前的字符复制到目标地址处,不要复制过长字符,会报Debug(自测),但strcpy在dev上测试不会报错,会照常打印。

strncpy

声明

char *strncpy(char *dest, const char *src, size_t n);

函数的返回值为目标字符串的首地址
形参为字符串的地址,用const修饰防止修改该地址内的内容,相较于strcpy,在末尾多一个形参,表明最大拷贝长度。
实现

char* my_strncpy(char* dest, const char* src, size_t n)
{
	assert(src);
	char* p = dest;
	int count = 0;
	while (n&& (*dest++ = *src++))n--;
	if (n)
	{
		while (--n)   *dest++ = '\0';
	}
	return p;
}

使用

#include<stdio.h>
#include<string.h>
int main()
{
	char* a = "abcdef";
	char b[10] = { 0 };
	char *c=strncpy(b,a, 3);
	printf("%s\n", b);//abc
	printf("%s", c);//abc
	return 0;
}

在这里插入图片描述
在这里插入图片描述
注意
strncpy拷贝指定长度的源字符串,若指定长度小于源字符串长度,则不会拷贝’\0’,只拷贝指定长度字符串;若指定长度大于源字符串长度,则拷贝’\0’来凑够指定长度。若指定长度或源字符串长度长于目标空间长度,编译器不会报错,会照常打印。

strncpy_s

相较于strncpy,它在第一个参数后面多一个形参表示目标空间的大小,以此来防止溢出。
但在vs测试中,若指定长度小于源字符串长度,则于strncpy不同,strncpy_s会在最后主动添加一个’/0’,而strncpy不会。若指定长度大于源字符串长度,则不会添加多余的’\0’。

strcat

声明

char *  strcat(char * dst,const char * src);

函数的返回值为目标字符串的首地址
形参为字符串的地址,用const修饰防止修改该地址内的内容
实现

char* my_strcat(char* dst, const char* src)
{
	assert(src);
	char* p = dst;
	while (*dst++);
	dst--;
	while (*dst++ = *src++);
	return p;
}

使用

#include<stdio.h>
#include<string.h>
int main()
{
	char* a = "abc\0def";
	char b[10] = {0};
	char*c=strcat(b,a);
	printf("%s", b);//abc
	printf("%s",c);//abc
}

注意
strcat会在目标字符串中第一个出现’\0’的位置开始追加源字符串,直到源字符串出现第一个’\0’为止,并将’\0’一同拷贝进去。

strcat_s

声明

errno_t  strcat(char * dst,size_t SizeInBytes,const char * src);

函数的返回值:正确连接返回0,错误返回非零
形参为字符串的地址,用const修饰防止修改该地址内的内容。相较于strcat,中间多了一个参数来说明最大目标空间,防止溢出。在测试中,strcat_s会对溢出报错,但strcat不会。
实现

errno_t  my_strcat_s(char* dst, size_t SizeInBytes, const char* src)
{
	assert(src);
	size_t count = 1;
	while (*dst++) count++;
	dst--;
	while (*dst++ = *src++)
	{
		if (++count > SizeInBytes)
		{
			*(--dst) = '\0';
			return -1;
		}
	}
	return 0;
}

使用

#include<stdio.h>
#include<string.h>
int main()
{
	char* a = "abc\0def";
	char b[10] = {0};
	int ret=strcat_s(b, sizeof(b) / sizeof(b[0]), a);
	printf("%s\n", b);//abc
	printf("%d", ret);//0
}

注意
strcat_s会在目标字符串中第一个出现’\0’的位置开始追加源字符串,直到源字符串出现第一个’\0’为止,并将’\0’一同拷贝进去。

strncat

声明

char * strncat (char * front, const char * back,size_t count);

函数的返回值:目标字符串的首地址
形参为字符串的地址,用const修饰防止修改该地址内的内容。相较于strcat,最后多了一个参数来说明最大链接长度。
实现

char* my_strncat(char* front, const char* back, size_t count)
{
	assert(back);
	char* p = front;
	while (count && (*front++ = *back++)) count--;
	if (count == 0)*front = '\0';
	if (count)
		while (--count)
			*front++ = '\0';
	return p;
}

使用

#include<stdio.h>
#include<string.h>
int main()
{
	char* a = "abcdefghijklmn";
	char b[10] = { 0,'#','#','#','#','#','#' ,'#','#',0};
	char* c = strncat(b,a,10);
	printf("%s\n", b);//abcdefghij,这里存在越界访问
	printf("%s\n",c);//abcdefghij
	return 0;
}

注意
strncat会在目标字符串第一个’\0’处开始链接源字符串,若指定长度小于源字符串长度,则将指定长度源字符串链接过去,并主动添加一个’/0’,这点与strncpy_s相似,与strncpy不同,但它缺少判断越界访问的条件,故当strncpy_s报错的情况下,strncat不会报错。若指定长度大于源字符串长度,则不足的用’\0’补齐。

strncat_s

相较于strncat,这个函数在第一个参数后面多一个参数表明目标字符串的长度,以此来防止越界访问。这个函数在防止越界访问的同时还会在链接时,若指定字符串小于源字符串长度主动添加’\0’;若指定字符串大于源字符串长度则不会添加多余的’\0’。

strcmp

声明

int strcmp(const char*src,const char*dst);

函数的返回值:>0:src>dst <0:src<dst 0:src=dst
形参为字符串的地址,用const修饰防止修改该地址内的内容。
实现

int my_strcmp(const char* src, const char* dst)
{
	assert(src && dst);
	while (*src == *dst && *dst!='\0')
	{
		src++;
		dst++;
	}
	return (*src - *dst);
}

使用

#include<stdio.h>
#include<string.h>
int main()
{
	char* a = "abcdefgi";
	char* b = "abcdefg";
	int ret=strcmp(a, b);//1
	printf("%d", ret);
	return 0;
}

注意
字符串的比较与双方的长度没有关系,在第一个不相等的地方就比较出了结果。双方比较的是第一个’\0’及以前的字符串。

strncmp

声明

int strncmp(const char*src,const char*dst,size_t n);

函数的返回值:>0:src>dst <0:src<dst 0:src=dst
形参为字符串的地址,用const修饰防止修改该地址内的内容。
实现

int my_strncmp(const char* src, const char* dst, size_t n)
{
	assert(src && dst);
	while (n != 0 && *src == *dst && *dst != '\0' )
	{
		src++;
		dst++;
		n--;
	}
	if (n > 0)
		return (*src - *dst);
	else
		return(*(--src) - *(--dst));
}

使用

#include<stdio.h>
#include<string.h>
int main()
{
	char* a = "abcd\0fgihij";
	char* b = "abcdf\0hij";
	int ret=strncmp(a, b, 8);
	printf("%d", ret);//-1
	return 0;
}

注意
字符串的比较与双方的长度没有关系,在第一个不相等的地方就比较出了结果。双方比较的是第一个’\0’及以前的字符串和指定比较长度中比较小的那一段字符串。

strstr

声明

const char * strstr ( const char * str1, const char * str2 );

函数的返回值:若能在str1中找到str2,则返回找到的位置地址;
若不能在str1中找到str2,则返回空指针。
形参为字符串的地址,用const修饰防止修改该地址内的内容。

使用

#include<stdio.h>
#include<string.h>
int main()
{
	char* a = "abcdef";
	char* b = "a\0e";
	char* c = strstr(a, b);
	printf("%s", c);//abcdef
	return 0;
}

注意
该函数使用的是str1和str2中第一个’\0’之前的字符进行匹配查找。

strtok

声明

char * strtok ( char * str, const char * delimiters );

以delimitres内的字符为分隔符,将const划分为更小的字符串。
函数的返回值:该函数返回被分解的第一个子字符串,如果没有可检索的字符串,则返回一个空指针。
形参为字符串的地址,用const修饰防止修改该地址内的内容。

使用

#include<stdio.h>
#include<string.h>
int main()
{
	char a[100] = "abcde-fhijk^lmn*opq-rst uvw\0xyz";
	char b[10] = "-^* ";
	char* c=strtok(a,b);//第一次划分要传字符串首地址
	while (c != NULL)
	{
		printf("%s\n", c);
		c = strtok(NULL, b);//后面的划分传NULL
	}
	for(int i=0;i<35;i++)
	{
		printf("%c",a[i]);
	}
	return 0;
}

在这里插入图片描述
注意
该函数是对str1中第一个’\0’之前的字符串进行切割,每次找到分割符后会将源字符串中的分割符替换成’\0’。空格也能当分割符,最后一次切割是遍历到str1中第一个’\0’为止,此时返回最后一个子字符串,下一次切割直接返回NULL。

iscntrl

声明

int iscntrl(int n);

函数的返回值:若是控制字符则返回非0值,若不是则返回0.

使用

#include<stdio.h>
#include<string.h>
int main()
{
	char* a = "k \n \a \t";
	for (int i = 0; i < strlen(a); i++)
	{
		printf("%d ", iscntrl(a[i]));
	}
	return 0;
}

在这里插入图片描述

注意
该函数查找字符串中’\0’之前的控制字符。

isspace

声明

int isspace(int c);

函数的返回值:若是空白字符则返回非0值,若不是则返回0.
如空格’ ‘,换页’\f’,换行’\n’,回车’\r’,制表符’\t’,垂直制表符’\v’

使用

#include<stdio.h>
#include<string.h>
int main()
{
	char* a = "k \n\a\t\v\r\f\0\t";
	for (int i = 0; i < 20; i++)
	{
		printf("%d ", isspace(a[i]));
	}
	return 0;
}

在这里插入图片描述

注意
'\0’不是空白字符。

isdigit

声明

int isdigit(int c);

函数的返回值:若是数字字符则返回非0值,若不是则返回0.

使用

#include<stdio.h>
#include<string.h>
int main()
{
	char a[13] = "012345\0 6789";
	for (int i = 0; i < 12; i++)
	{
		printf("%d ", isdigit(a[i]));
	}
	return 0;
}

在这里插入图片描述
注意
只能判断一个字符。

isxdigit

声明

int isxdigit(int c);

函数的返回值:若是十六进制字符则返回非0值,若不是则返回0.
0~9,abcdef,ABCDEF

使用

#include<stdio.h>
#include<string.h>
int main()
{
	char a[] = "0123456789abcdefABCDEF";
	for (int i = 0; i < strlen(a); i++)
	{
		printf("%d ", isxdigit(a[i]));
	}
	return 0;
}

在这里插入图片描述

注意
只能判断一个字符。

islower

声明

int islower(int c);

函数的返回值:若是小写字母字符则返回非0值,若不是则返回0.
a~z

使用

#include<stdio.h>
#include<string.h>
int main()
{
	char a[27] = "abcdefghijklmnopqrstuvwxyz";
	for (int i = 0; i < 27; i++)
	{
		printf("%d ", islower(a[i]));
	}
	return 0;
}

在这里插入图片描述
注意
只能判断一个字符。

isupper

声明

int isupper(int c);

函数的返回值:若是大写字母字符则返回非0值,若不是则返回0.
A~Z

使用

#include<stdio.h>
#include<string.h>
int main()
{
	char a[27] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
	for (int i = 0; i < 27; i++)
	{
		printf("%d ", isupper(a[i]));
	}
	return 0;
}

在这里插入图片描述
注意
只能判断一个字符。

isalpha

声明

int isalpha(int c);

函数的返回值:若是大写字母字符或小写字母字符则返回非0值,若不是则返回0.
A~Z,
a~z
使用

#include<stdio.h>
#include<string.h>
int main()
{
	char a[27] = "ABC abc\t\n\a";
	for (int i = 0; i < strlen(a); i++)
	{
		printf("%d ", isalpha(a[i]));
	}
	return 0;
}

在这里插入图片描述

注意
只能判断一个字符。

isalnum

声明

int isalnum(int c);

函数的返回值:若是大写字母字符或小写字母字符或数字字符则返回非0值,若不是则返回0.
0~9,
A~Z,
a~z
使用

#include<stdio.h>
#include<string.h>
int main()
{
	char a[27] = "ABC abc 123\t\n\a";
	for (int i = 0; i < strlen(a); i++)
	{
		printf("%d ", isalnum(a[i]));
	}
	return 0;
}

在这里插入图片描述
注意
只能判断一个字符。

ispunct

声明

int ispunct(int c);

函数的返回值:若是非字母和数字的可打印图形符则返回非0值,若不是则返回0.
使用

#include<stdio.h>
#include<string.h>
int main()
{
	char a[27] = "ABC abc 123\t\n\a^!*,.@#";
	for (int i = 0; i < strlen(a); i++)
	{
		printf("%d ", ispunct(a[i]));
	}
	return 0;
}

在这里插入图片描述
注意
只能判断一个字符。

isgraph

声明

int isgraph(int c);

函数的返回值:若是图形符则返回非0值,若不是则返回0.
! " # $ % & ’ ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~
注意
只能判断一个字符。

tolower

声明

int tolower(int c);

函数的返回值:如果 c 有相对应的小写字母,则该函数返回 c 的小写字母,否则 c 保持不变。返回值是一个可被隐式转换为 char 类型的 int 值。
使用

#include<stdio.h>
#include<string.h>
int main()
{
	char a[30] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ@!#";
	for (int i = 0; i < strlen(a); i++)
	{
		printf("%c ", tolower(a[i]));
	}
	return 0;
}

a b c d e f g h i j k l m n o p q r s t u v w x y z @ ! #
注意
只能判断一个字符。

toupper

声明

int toupper(int c);

函数的返回值:如果 c 有相对应的大写字母,则该函数返回 c 的小写字母,否则 c 保持不变。返回值是一个可被隐式转换为 char 类型的 int 值。
使用

#include<stdio.h>
#include<string.h>
int main()
{
	char a[30] = "abcdefghijklmnopqrstuvwxyz@!#";
	for (int i = 0; i < strlen(a); i++)
	{
		printf("%c ", toupper(a[i]));
	}
	return 0;
}

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z @ ! #
注意
只能判断一个字符。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值