朋友们,今天追秋给大家带来的是一些函数的介绍,包括字符函数、字符串函数和内存函数。
字符串函数
字符串函数分为以下几类:
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 <string.h>
int main()
{
const char* p1 = "abcd";
const char* p2 = "abcdefg";
if (strlen(p1) - strlen(p2) >= 0)
printf(">=\n");
else
printf("<\n");
return 0;
}
运行结果:
由此可见,同样的整形数据运行结果为负数的时候,无符号整形运行结果为负数,这也是整个函数使用时需要注意的地方。
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结尾时,依然进行拷贝,此时程序崩溃:
目标空间足够大,且将源字符串空间\0进行拷贝
int main()
{
char arr1[20] = "xxxxxxxxx";
char arr2[] = { 'a','b','c' ,'\0'};
strcpy(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
目标空间无法修改
int main()
{
char* p = "abcdefg";
char arr[] = { 'a','b','c','\0' };
strcpy(p, arr);
printf("%s\n", p);
return 0;
}
指针p指向的是常量字符串,而常量字符串是无法修改的,即:目标空间无法修改,程序报错;
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也拷贝到了目标字符串空间,同时覆盖掉原本的数据,
拷贝自身
可以看到,在编译器VS2019上对字符串自身进行拷贝的时候,编译器报错,
但是注意,该函数对自身进行拷贝功能,C语言标准并未定义,该函数是否可以拷贝自身是由编译器自身决定的,根据使用的编译器的不同会出现不同的效果
strcmp
int strcmp (const char* str1, const char* str2);
使用规则:
第一个字符串大于、等于、小于第二个字符串时,返回大于0、等于0、小于0的数字;
2.返回类型为int型;
举例:
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个;
注:而当大小足够时,不会再字符串后面自动追加\0;
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.
而当源字符串空间不足时,该函数依然将源字符串拷贝到目标空间,但拷贝完源字符串时就立即结束,不在进行多余的操作;
strncmp
这个函数在功能上与strcmp的区别就是比较长度的限制,参数部分多了一个用于限制比较次数的参数;
举例:
strstr
char* strstr (const char* str1; const char* str2);
功能:在字符串str1中查找字符串str2;如果找到了,就返回str1中str2首次出现的位置;如果没找到,就返回NULL(空指针);
注:该库函数返回的是地址;且不可被修改;
举例:
场景一:能找到字符串str2;
场景二:找不到字符串str2;
场景三:需要查找的字符串str2为空:
可以看到:当需要查找的字符串中没有字符,仅有一个\0时,返回的是被查找字符串str1的起始地址;
场景四:被查找字符串str1是空字符串;
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 指针.
举例:
我们可以看到,此代码虽然可以实现字符串切割的目的,但是实际作用局限性比较大,实现起来也很复杂,我们可以改进以下这个代码:
strerror
char * strerror ( int errnum );
功能:返回错误码,所对应的错误信息。
举例:
打印部分错误码:
字符函数
字符分类函数
函数 如果他的参数符合下列条件就返回真
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;
}
运行结果:
当然这里的字符型数据的例子也是给到大家:
memmove
作用:和memcpy基本一致,在函数memcpy的基础上增加了一个功能:自己拷贝自己的数据;
举例:
#include <string.h>
int main()
{
int arr[20] = { 1,2,3,4,5,6,7,8,9,10 };
memmove(arr+2, arr, 5 * sizeof(int));
return 0;
}
注:对于内存函数memcpy和memmove的功能,标准规定:memmove可以对内存空间重叠的数据进行拷贝,memcpy只对内存空间不重叠的数据进行拷贝,而在编译器上是不进行强制要求的,也就是说:在不同的编译器上memcpy的功能可能有所差异,也就是是否可以拷贝内存空间重叠的数据。
memset
功能:此函数为内存设置函数,是以字节为单位来将目标空间设置为特定值;
举例:
int main()
{
char arr[10] = "abcdefg";
memset(arr, 'x', 6);
printf("%s\n", arr);
return 0;
}
运行结果:
但是当遇到整形数据等等这些单位长度大于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;
}
运行结果:
因为是以字节为单位,而整形数据是有四个字节,拿第一个数据举例,设置结束后数据以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;
}
运行结果: