C语言零基础第15讲:字符函数和字符串函数
目录
1.字符分类函数
2.字符转换函数
3.strlen的使用和模拟实现
4.strcpy的使用和模拟实现
5.strcat的使用和模拟实现
6.strcmp的使用和模拟实现
7.strncpy的使用
8.strncat的使用
9.strncmp的使用
10.strstr的使用和模拟实现
11.strtok函数的使用
12.strerror函数的使用
正文开始
在写代码的过程中,我们可能经常要处理字符和字符串,为了方便操作字符和字符串,C语言标准库提供了一系列库函数。我们可以一起来看看:
1.字符分类函数
C语言中有一批函数,是专门对字符进行分类的,这些函数对应的头文件是:ctype.h。
我们来看个例子:
我们来做一个练习:找出数组中的十进制数字,并打印出来。如下:
我们再来看一个练习:写一个代码,将字符串中的小写字母转为大写字母,其他字符不变。如下:
2.字符转换函数
C语言中提供了2个字符转换函数:
- int tolower( int c ); :将参数所传进去的大写字母转为小写字母。
- int toupper ( int c ); :将参数所转进去的小写字母转为大写字母。
将小写转大写,可以用-32来完成。将大写转小写,可以用+32来完成。不过,有了字符转换函数,我们可以直接转换。
我们可以来看看例子:
3.strlen的使用和模拟实现
strlen函数的原型如下:
size_t strlen( const char* str);
- 参数指向的字符串,必须要以'\0'结束。
- strlen函数返回的是,字符串中在'\0'前面出现的字符个数(不包含'\0')。
- 对应的头文件是:string.h。
- 返回值类型为size_t,是无符号的。
对于返回值类型为size_t这一点,是一个易错点。请看下面的例子:
对于上面的代码,我们可能会觉得,arr2的长度比arr1短,那么应该会打印arr2 <= arr1。然而结果是arr2 > arr1。这是因为,strlen函数的返回值是无符号整数,两个无符号数相减,得到的还是无符号数。我们知道,两个长度相减,得到的是-3,存储的也是-3的补码,但由于是无符号整型,这个补码会被当做原码,会变成一个很大的无符号数。
如果想要实现原意,可以这样进行强制类型转换:(int)strlen(arr2) - (int)strlen(arr1)。或者这样写:if(strlen(arr2) > strlen(arr1))。
我们来看看strlen的模拟实现:
4.strcpy的使用和模拟实现
strcpy函数的原型如下:
char* strcpy(char* destination, const char* source);
- 前一个参数是目标字符串的指针,要将被复制的内容赋给目标字符串,所以不加const修饰。
- 后一个参数是源字符串的指针,仅仅是复制源字符串的内容,不做任何修改,所以使用const修饰。
- 源字符串必须以'\0'结束,这个'\0'也会被拷贝到目标空间。
- 目标空间必须足够大,以确保能够存放得下源字符串。
- 目标空间必须是可修改的。
- 对应的头文件:string.h。
我们来看一个示例:
我们来看看strcpy的模拟实现:
5.strcat的使用和模拟实现
strcat函数的原型如下:
char* strcat (char* destination, const char* source);
- 把源字符串的内容追加到目标字符串的后面。
- 源字符串必须以'\0'结束。
- 目标字符串也得有'\0',否则不知道从哪里开始追加。
- 目标空间必须足够大。
- 目标空间必须可修改。
- 对应的头文件:string.h。
我们来看一个示例:
我们再来看看strcat的模拟实现:
6.strcmp的使用和模拟实现
strcmp函数的原型如下:
int strcmp (const char* str1, const char* str2);
- 意为string compare,即字符串比较。
- 比较的是2个字符串的大小,第一个字符串大于第二个字符串,则返回一个大于0的数字,等于则返回0,小于则返回一个小于0的数字。
- 按字符的ASCII码值从左向右逐个比较, 直到遇到不同的字符,或者'\0'。
- 比如:"abchigk"和"abcpqrs",前面的字符都是abc,直到遇到了h和p作比较,显然p的ASCII码值要更大,所以结果为前一个字符串<后一个字符串,返回一个小于0的数字。
- 对应的头文件是:string.h。
我们来看一个示例:
我们来看一下strcmp函数的模拟实现:
7.strncpy的使用
strncpy函数的原型如下:
char* strncpy (char* destination, const char* source, size_t num);
- 从源字符串拷贝num个字符到目标空间。
- 如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。
- 对应的头文件:string.h。
我们来看一个示例:
8.strncat的使用
strncat函数的原型如下:
char* strncat (char* destnation, const char* source, size_t num);
- 将源字符串的前num个字符追加到目标字符串的后面,再追加一个'\0'。
- 如果源字符串的长度小于num,只会将源字符串中从左到'\0'的内容追加到目标字符串的后面。
- 对应的头文件是:string.h。
我们来看一个示例:
9.strncmp的使用
strncmp函数的原型如下:
int strncmp (const char* str1, const char* str2, size_t num);
- 比较2个字符串的前num个字符。
- 逐个往后比较字符的ASCII码值,直到遇到不相同的字符或'\0'。
- 大于则返回一个大于0的数,小于则返回一个小于0的数。如果所有字符都相同,则返回0。
- 对应的头文件是:string.h。
我们来看一个示例:
10.strstr的使用和模拟实现
strstr函数的原型如下:
版本1:
const char* strstr (const char* str1, const char* str2);
版本2:char* strstr ( char* str1, const char* str2);
- 在str1字符串中去找str2字符串。如果找到了,就返回这个字符串在str1中的起始地址,如果没找到,返回空指针。
- 如果多次出现,找的是第一次出现的位置。
- 对应的头文件:string.h。
我们来看一个示例:
我们再来看一下它的模拟实现:
上面的代码是一个常规的模拟实现,结合画图会更好理解。
关于字符串查找,有一种算法叫做KMP算法,特点是高效,但代码比较难以理解。
11.strtok函数的使用
strtok函数的原型如下:
char* strtok (char* str, const char* sep);
以字符串"abcd@qq.com"为例,如果我们不想看到'@'和' . '这些分隔符,而是想要提取出abcd、qq和com这些内容。我们就可以使用strtok函数,请看下面的解释:
- 第一个参数str,就是传入字符串"abcd@qq.com"。
- 不过,为了不修改原来的字符串,我们一般把原字符串的内容拷贝到另一个变量中,用这个临时变量来传参。比如:char tmp[20] = {0}; strcpy(tmp, "abcd@qq.com");
- sep参数是一个字符串,里面包括了我们需要去掉的分隔符,如:const char* sep = "@.";
- 第一次调用strtok函数:strtok(tmp, sep);,此时tmp变为:"abcd\0qq.com",函数会返回a的地址,把这个地址传入printf,可以打印出abcd。
- 刚刚调用strtok函数时,函数找到了第一个标记:@,将其变为\0,并保存了这个位置,下一次调用的时候,就会从这个位置开始往后查找下一个标记。
- 第二次调用strtok函数:strtok(NULL, sep);,此时tmp变为:"abcd\0qq\0com",函数会返回q的地址,把这个地址传入printf,可以打印出qq。
- 刚刚调用strtok函数时,函数找到了第二个标记:. ,将其变为\0,并保存了这个位置,下一次调用的时候,就会从这个位置开始往后查找下一个标记。
- 第三次调用strtok函数:strtok(NULL, sep);,没有找到标记,tmp不变,函数返回c的地址,把这个地址传入printf,可以打印出com。
- 如果继续调用,已经找不到更多的标记了,函数会返回NULL。
- 对应的头文件:string.h。
我们来看一个示例:
当然了,上面的代码不够普适,如果我们不知道字符串中到底有多少个分隔符,也就不知道应该调用多少次,那该怎么办呢?请看代码:
12.strerror函数的使用
strerror函数的原型如下:
char* strerror (int errnum);
- 在不同的系统和C语言标准库中,都规定了一些错误码,一般是放在errno.h这个头文件中进行说明。
- C语言程序在启动的时候,就会使用一个全局变量errno来记录当前程序的错误码。
- 如果想使用全局变量errno,需要包含对应的头文件:errno.h。
- 程序刚启动的时候,errno是0,表示没有错误。
- 当我们在使用库函数的时候,如果发生了某种错误,就会将对应的错误码放在errno中。
- 每一个错误码的数字,都是整数,代表了不同的错误信息。
- strerror函数就可以将错误码所对应的错误信息的字符串起始地址返回。
- strerror的使用需要包含对应的头文件:string.h。
我们来看看一些错误码对应的错误信息:
我们来看看strerror函数的应用:
我们还可以了解一下perror函数,相当于printf + strerror的作用,可以直接将错误信息打印出来,还可以传入一个参数,额外加上一个字符串:
完结