字符函数、字符串函数和内存函数

朋友们,今天追秋给大家带来的是一些函数的介绍,包括字符函数、字符串函数和内存函数。

字符串函数

字符串函数分为以下几类:
1.长度不受限制的字符串函数:strlen;strcpy;strcat;strcmp;
2.长度受限制的字符串函数:strncpy;strncat;strncmp.

3.还有一些特殊用法的字符串:strstr;strtok;strerror;
下面给大家逐一介绍这些字符串函数:

strlen

size_t strlen (const chatr str)*

使用规则:
1.我们知道字符串是以\0作为结束表示,而strlen函数统计的就是字符串\0之前的字符个数;
2.该函数的返回类型是 size_t 类型,是无符号整形,注意:无符号整形进行运算时不会出现负数的情况出现;
3.该函数的参数类型必须以\0结尾;

例题:

#include 
int main()
{
	const char* p1 = "abcd";
	const char* p2 = "abcdefg";
	if (strlen(p1) - strlen(p2) >= 0)
		printf(">=\n");
	else
		printf("<\n");
	return 0;
}

运行结果:
字符函数、字符串函数和内存函数_第1张图片
由此可见,同样的整形数据运行结果为负数的时候,无符号整形运行结果为负数,这也是整个函数使用时需要注意的地方。

strcpy

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

使用规则
1.源字符串必须以\0结尾;
2.会将源字符串中的\0也拷贝到目标字符串当中;
3.目标空间必须足够大,确保可以将源字符串全部拷贝到目标空间当中;
4.目标空间必须可变;

举例:

源字符串没有以\0结尾

int main()
{
	char arr1[20] = { 0 };
	char arr2[] = { 'a','b','c' };
	strcpy(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

当源字符串中没有\0结尾时,依然进行拷贝,此时程序崩溃:
字符函数、字符串函数和内存函数_第2张图片

目标空间足够大,且将源字符串空间\0进行拷贝

int main()
{
	char arr1[20] = "xxxxxxxxx";
	char arr2[] = { 'a','b','c' ,'\0'};
	strcpy(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

字符函数、字符串函数和内存函数_第3张图片

目标空间无法修改

int main()
{
	char* p = "abcdefg";
	char arr[] = { 'a','b','c','\0' };
	strcpy(p, arr);
	printf("%s\n", p);
	return 0;
}

指针p指向的是常量字符串,而常量字符串是无法修改的,即:目标空间无法修改,程序报错;
字符函数、字符串函数和内存函数_第4张图片

strcat

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

使用规则
1.源字符串必须以\0结尾;
2.会将源字符串中的\0拷贝到目标空间中;
3.目标空间必须可变;

拷贝字符串

int main()
{
	char arr1[20] = "abcd\0xxxxxxx";
	char arr2[] = "efg";
	strcat(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

运行结果:
可以看到,该函数将源字符串空间中的\0也拷贝到了目标字符串空间,同时覆盖掉原本的数据,
字符函数、字符串函数和内存函数_第5张图片

拷贝自身

可以看到,在编译器VS2019上对字符串自身进行拷贝的时候,编译器报错,
但是注意,该函数对自身进行拷贝功能,C语言标准并未定义,该函数是否可以拷贝自身是由编译器自身决定的,根据使用的编译器的不同会出现不同的效果
字符函数、字符串函数和内存函数_第6张图片

strcmp

int strcmp (const char* str1, const char* str2);

使用规则:
第一个字符串大于、等于、小于第二个字符串时,返回大于0、等于0、小于0的数字;
2.返回类型为int型;

举例:
字符函数、字符串函数和内存函数_第7张图片

strncpy

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

使用规则:
1.从源字符串空间拷贝num的字符到目标空间中;
2.如果源字符串长度小于num,则拷贝完源字符串后,在目标空间后面追加0,直到num个;
注:该函数的使用规则和strcpy的使用规则完全一样,仅仅是多了一个参数的限制,该参数的类型是size_t类型,作用是限制该函数的使用次数,对于strcpy函数的使用基础上进行进一步的细化提升。

举例:

int main()
{
	char arr1[20] = "xxxxxxxxxxxx";
	char arr2[] = "abcd";
	strncpy(arr1, arr2, 6);
	printf("%s\n", arr1);
	return 0;
}

运行结果:
可以看到:当源字符串大小不足时,该函数会自动给目标空间补齐\0,直到num个;
字符函数、字符串函数和内存函数_第8张图片
注:而当大小足够时,不会再字符串后面自动追加\0;
字符函数、字符串函数和内存函数_第9张图片

strncat

char* strncat (char* destination , const char* source , size_t num ) ;

该函数和strncat类似,功能和strcat一样,只是在功能上更加细化;
举例:

int main()
{
	char arr1[20] = "123\0xxxxxxx";
	char arr2[] = "abcd";
	strncat(arr1, arr2, 3);
	printf("%s\n", arr1);
	return 0;
}

运行结果:
可以看到:在进行字符串追加的时候,在源字符串空间足够的情况下,将字符串拷贝结束之后会追加一个\0在目标空间的末尾;
即:strncat在追加字符串的时候会在字符串的末尾给到一个\0,或者更多的\0;而strncpy只有在源字符串空间不足的情况下才会追加\0.
字符函数、字符串函数和内存函数_第10张图片
而当源字符串空间不足时,该函数依然将源字符串拷贝到目标空间,但拷贝完源字符串时就立即结束,不在进行多余的操作;
字符函数、字符串函数和内存函数_第11张图片

strncmp

这个函数在功能上与strcmp的区别就是比较长度的限制,参数部分多了一个用于限制比较次数的参数;

举例:
字符函数、字符串函数和内存函数_第12张图片
字符函数、字符串函数和内存函数_第13张图片

strstr

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

功能:在字符串str1中查找字符串str2;如果找到了,就返回str1中str2首次出现的位置;如果没找到,就返回NULL(空指针);
注:该库函数返回的是地址;且不可被修改;

举例:
场景一:能找到字符串str2;字符函数、字符串函数和内存函数_第14张图片
场景二:找不到字符串str2;
字符函数、字符串函数和内存函数_第15张图片
场景三:需要查找的字符串str2为空:
可以看到:当需要查找的字符串中没有字符,仅有一个\0时,返回的是被查找字符串str1的起始地址;
字符函数、字符串函数和内存函数_第16张图片
场景四:被查找字符串str1是空字符串;
字符函数、字符串函数和内存函数_第17张图片

strtok

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

使用规则:
1.sep参数是个字符串,定义了用作分隔符的字符集合
2.第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。
3.strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)
4.strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
5.strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
6.如果字符串中不存在更多的标记,则返回 NULL 指针.

举例:字符函数、字符串函数和内存函数_第18张图片
我们可以看到,此代码虽然可以实现字符串切割的目的,但是实际作用局限性比较大,实现起来也很复杂,我们可以改进以下这个代码:
字符函数、字符串函数和内存函数_第19张图片

strerror

char * strerror ( int errnum );

功能:返回错误码,所对应的错误信息。

举例:
打印部分错误码:字符函数、字符串函数和内存函数_第20张图片

字符函数

字符分类函数

函数 如果他的参数符合下列条件就返回真
iscntrl 任何控制字符
isspace 空白字符:空格‘ ’,换页‘\f’,换行’\n’,回车‘\r’,制表符’\t’或者垂直制表符’\v’
isdigit 十进制数字 0~9
isxdigit 十六进制数字,包括所有十进制数字,小写字母af,大写字母AF
islower 小写字母a~z
isupper 大写字母A~Z
isalpha 字母az或AZ
isalnum 字母或者数字,az,AZ,0~9
ispunct 标点符号,任何不属于数字或者字母的图形字符(可打印)
isgraph 任何图形字符
isprint 任何可打印字符,包括图形字符和空白字符

字符转换函数

int tolower ( int c ); 作用:大写转小写
int toupper ( int c ); 作用:小写转大写

注:传递参数是字母,但是在其中运算是通过ASCII码值运算的,因此参数部分是整形;
这两个函数的返回值为整形,因此要用整形数据来接收,传递的是ASCII码值;

内存函数

我们直到,在计算机在进行数据存储的时候,不仅仅是存储字符型的数据,还要存储其它类型的数据,比如整形,长整型,短整型等一些数据类型。当然,这些数据类型也有相对于的函数来进行拷贝、复制等操作。下面我们来介绍以下这些函数

memcpy

作用:和strcpy类似,只是拷贝的数据类型包括但不限制于字符型数据,可以拷贝其它任意类型的数据。

举例:

int main()
{
	int arr1[10] = { 0 };
	int arr2[] = { 1,2,3,4,5,6,7,8,9,10 };
	memcpy(arr1, arr2, 5 * sizeof(int));
	return 0;
}

运行结果:
字符函数、字符串函数和内存函数_第21张图片
当然这里的字符型数据的例子也是给到大家:
字符函数、字符串函数和内存函数_第22张图片

memmove

作用:和memcpy基本一致,在函数memcpy的基础上增加了一个功能:自己拷贝自己的数据;

举例:

#include 
int main()
{
	int arr[20] = { 1,2,3,4,5,6,7,8,9,10 };
	memmove(arr+2, arr, 5 * sizeof(int));
	return 0;
}

字符函数、字符串函数和内存函数_第23张图片
注:对于内存函数memcpy和memmove的功能,标准规定:memmove可以对内存空间重叠的数据进行拷贝,memcpy只对内存空间不重叠的数据进行拷贝,而在编译器上是不进行强制要求的,也就是说:在不同的编译器上memcpy的功能可能有所差异,也就是是否可以拷贝内存空间重叠的数据。

memset

功能:此函数为内存设置函数,是以字节为单位来将目标空间设置为特定值;

举例:

int main()
{
	char arr[10] = "abcdefg";
	memset(arr, 'x', 6);
	printf("%s\n", arr);
	return 0;
}

运行结果:
字符函数、字符串函数和内存函数_第24张图片
但是当遇到整形数据等等这些单位长度大于1字节的数据类型的数据时,这个函数的功能就不太方便去重置目标空间的的值;
例如:我们想要将整形数组中的前五个数据改成0;

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	memset(arr, 1, 5*sizeof(int));
	for (int i = 0; i < 10; i++)
	{
		printf("%d\n", arr[i]);
	}
	return 0;
}

运行结果:
字符函数、字符串函数和内存函数_第25张图片
因为是以字节为单位,而整形数据是有四个字节,拿第一个数据举例,设置结束后数据以16进制形式呈现:01010101,即16843009,实际结果和我们的预期结果相差甚远;因此在使用该函数的时候要小心谨慎使用!

memcmp

功能:
1.和函数strcmp类似,但是作用范围更大,可以比较任意类型的数据的大小。
2.结果为大于、等于、小于的时候,返回值给到的是大于0、等于0、小于0的数据,用整形来接收。
3.比较的单位是字节

举例:

int main()
{
	int arr1[] = { 1,2,3,4,5,6 };
	int arr2[] = { 1,2,3,4,6 };
	int ret = memcmp(arr1, arr2, 4 * sizeof(int));
	printf("%d\n", ret);
	return 0;
}

运行结果:
字符函数、字符串函数和内存函数_第26张图片
字符函数、字符串函数和内存函数_第27张图片

你可能感兴趣的:(c#,c++)