字符串函数

strtok函数

strtok函数的规则:

1.参数1是指定一个字符串,它包含0个或多个由参数2字符串中一个或多个分隔符分割的标记

2.参数2是个字符串,定义了用作分隔符的字符集合。

3.strtok函数找到参数1的下一个标记,并将其用\0结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可以修改。)

4.strtok函数的第一个参数不为NULL,函数将找到参数1中第一个标记,strtok将保存它在字符串中的位置

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

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

结合下面的例子:

当执行strtok函数后,如下图:

实际上,我们切割时并不清楚需要切割几次,因此我们需要通过循环进行切割

分析:很明显,第一次打印abcd。第二次打印ef是因为,参数1为NULL,根据规则,它会从上一次保存的位置继续查找标记,第三次打印也是如此。

strerror函数

strerror是将错误码翻译成错误信息,返回错误信息的字符串的起始地址。

strerror里的参数是整形,上面是各种类型的错误信息。

C语言中使用库函数的时候,如果发生错误,会将错误码放在errno的变量中,errno是一个全局变量,可以直接使用的。如上图,我们暂时不用管别的,我们只需要知道strerror里的errno存放错误码即可。

这里,我们再简单介绍下另一个类似的函数perror

perror函数是直接打印错误码所对应的错误信息。perror==printf+strerror。

我们简单修改下上面的代码,发现:perror里面的内容,是我们自定义的信息,在打印完我们的信息后,他会自动在后面补上:号然后加上错误信息。因此也可以知道,perror的好处就是比较方便,会自动识别错误信息。但是他也会自动打印出错误信息。

字符函数

字符分类函数

字符分类函数有如下:

因为每个函数的使用方式基本相同,我们就举一个来简单说明:

当我们使用上面的函数时,我们需用引用头文件,如果函数内为真则返回不等于0的数,如果为假,则返回0。

字符转换函数

字符转换函数有tolower和toupper。他们的返回值和参数都是int,即字符的ASCII值。如下图,如果参数是小写则转换成大写,如果是大写,则不变。

内存函数

memcpy函数

memcpy函数跟strcpy函数有相似之处,不过memcpy可以拷贝任何类型。mencpy的参数1是目标空间,参数2是原始空间,参数3是拷贝的个数,单位是字节,这里指的是把arr2的前5个元素拷贝到arr1中(因为一个整形是4个字节,5个就是20个字节)。

void* my_memcpy(void* dest, const void* src, size_t sz){assert(dest && src);while (sz--){*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}}

上方是memcpy的模拟实现。

如上图,如果我们想把前五个数(1,2,3,4,5),从第3个数开始的5个数(3,4,5,6,7)拷贝过去,我们希望得到的结果是{1,2,1,2,3,4,5,8,9,10}。可是最后的结果却不是。这是因为在拷贝的重叠部分被改变了。

前面的拷贝是不重叠内存的拷贝,可以用memcpy。如果是重叠内存的拷贝,可以用memmove函数。

memmove函数

memmove函数的返回值和参数与memcpy的一模一样,如上图,使用它就能达到我们所想要的结果。

void* my_memmove(void* dest, const void* src, size_t sz){assert(dest && src);void* ret = dest;if (dest 后int i = 0;for (i = 0; i 前while (sz--){*((char*)dest + sz) = *((char*)src + sz);}}return ret;}int main(){int arr[] = { 1,2,3,4,5,6,7,8,9,10 };memmove(arr+2, arr, 20);int i;for (i = 0; i < 10; i++)printf("%d ", arr[i]);return 0;}

上方是模拟memmove函数的实现。

分析: 当原始空间的地址大于目标空间地址时,我们需要从前往后拷贝原始字符串到目标空间。

否则,我们就需要从后往前进行拷贝,这样就不会因为重叠而导致结果达不到预期。while循环中,sz–,起初sz是20,进入循环内变成19,强转后的dest+sz刚好指向最后一个字节,就能从后往前进行拷贝。

memset函数

memset函数是用来设置内存的,以字节为单位进行设置。如上图,参数1是起始地址,参数2是要设置的内容,参数3是设置的字节个数。

memcmp函数

memcmp函数与strcmp函数类似,不过strcmp函数只能进行字符串的比较,memcmp是内存块的比较,可以比较任意类型的数据。如下图:

参数1和参数2与strcmp的一样,参数3指比较前n个字节个数的数据,因为int占4个字节,比较前3个元素,大小相同则返回0。

如上图,我们比较大小的时候,不能单纯比较数字,而要看他们在内存中是怎样的,这样才能得出正确结果。