文章目录
- 一、字符分类函数
- 二、字符转换函数
- 三、strlen函数:计算字符串长度
- 功能说明
- 使用示例
- 模拟实现
- 四、strcpy函数:字符串拷贝
- 功能说明
- 模拟实现
- 五、strcat函数:字符串追加
- 功能说明
- 模拟实现
- 六、strcmp函数:字符串比较
- 比较规则
- 模拟实现
- 七、strncpy函数:指定长度的字符串拷贝
- 功能说明
- 八、strncat函数:指定长度的字符串追加
- 功能说明
- 九、strncmp函数:指定长度的字符串比较
- 功能说明
- 十、strstr函数:查找子字符串
- 功能说明
- 模拟实现
- 十一、strtok函数:字符串分割
- 功能说明
- 十二、strerror函数:获取错误信息
- 功能说明
- 相关函数:perror
在C语言编程中,字符和字符串的处理是非常基础且重要的操作。C语言标准库提供了一系列专门用于处理字符和字符串的库函数,掌握这些函数能极大地提高编程效率。本文将详细介绍这些函数的使用方法和模拟实现,帮助大家深入理解并灵活运用。
一、字符分类函数
字符分类函数用于判断一个字符属于哪种类型,它们都包含在ctype.h
头文件中。这些函数的参数为 int
类型 , 返回值为 非0(真)或0(假)。
以下是常用的字符分类函数及其功能:
iscntrl
:判断是否为控制字符isspace
:判断是否为空白字符(空格' '
、换页'\f'
、换行'\n'
、回车'\r'
、制表符'\t'
、垂直制表符'\v'
)isdigit
:判断是否为十进制数字(0~9)isxdigit
:判断是否为十六进制数字(0~9、a~f、A~F)islower
:判断是否为小写字母(a~z)isupper
:判断是否为大写字母(A~Z)isalpha
:判断是否为字母(a~z或A~Z)isalnum
:判断是否为字母或数字(a~z、A~Z、0~9)ispunct
:判断是否为标点符号(不属于数字或字母的可打印图形字符)isgraph
:判断是否为任何图形字符isprint
:判断是否为任何可打印字符(包括图形字符和空白字符)
示例:使用islower
函数
islower
函数用于判断参数是否为小写字母,是则返回非0整数,否则返回0。
下面的代码将字符串中的小写字母转换为大写,其他字符不变:
#include <stdio.h>
#include <ctype.h>
int main ()
{int i = 0;char str[] = "Test String.\n";char c;while (str[i]){c = str[i];if (islower(c)) c -= 32;putchar(c);i++;}return 0;
}
二、字符转换函数
C语言提供了两个常用的字符转换函数,同样包含在ctype.h
头文件中:
int tolower(int c)
:将大写字母转换为小写int toupper(int c)
:将小写字母转换为大写
示例:使用toupper
函数
将上面的小写转大写代码用toupper
函数改写:
#include <stdio.h>
#include <ctype.h>
int main ()
{int i = 0;char str[] = "Test String.\n";char c;while (str[i]){c = str[i];if (islower(c)) c = toupper(c);putchar(c);i++;}return 0;
}
三、strlen函数:计算字符串长度
strlen
函数用于计算字符串的长度,其原型为:
size_t strlen(const char *str);
功能说明
- 字符串以’\0’作为结束标志,
strlen
返回的是’\0’前面的字符个数(不包含’\0’) - 参数指向的字符串必须以’\0’结束
- 返回值为
size_t
(无符号整数),这一点在使用时容易出错
使用示例
#include <stdio.h>
#include <string.h>
int main()
{const char* str1 = "abcdef";const char* str2 = "bbb";if(strlen(str2) - strlen(str1) > 0)printf("str2>str1\n");elseprintf("str1>str2\n");return 0;
}
注意:由于
strlen
返回值是无符号数,上面代码中strlen(str2)-strlen(str1)
的结果是无符号数,可能会出现与预期不符的情况。
模拟实现
strlen
有多种模拟实现方式:
- 计数器方式
int my_strlen(const char *str)
{int count = 0;assert(str); // 确保指针非空while(*str){count++;str++;}return count;
}
- 递归方式(不创建临时变量)
int my_strlen(const char *str)
{assert(str);if(*str == '\0')return 0;elsereturn 1 + my_strlen(str + 1);
}
- 指针-指针方式
int my_strlen(char *s)
{assert(s);char *p = s;while(*p != '\0')p++;return p - s;
}
四、strcpy函数:字符串拷贝
strcpy
函数用于将源字符串拷贝到目标空间,原型为:
char* strcpy(char *destination, const char *source);
功能说明
- 源字符串必须以’\0’结束
- 会将源字符串中的’\0’拷贝到目标空间
- 目标空间必须足够大,以容纳源字符串
- 目标空间必须可修改
模拟实现
char *my_strcpy(char *dest, const char*src)
{char *ret = dest;assert(dest != NULL);assert(src != NULL);while((*dest++ = *src++)){;}return ret;
}
实现说明:循环中先将
*src
赋值给*dest
,然后两者都自增,直到拷贝到’\0’时,循环条件为假,结束循环。
五、strcat函数:字符串追加
strcat
函数用于将源字符串追加到目标字符串末尾,原型为:
char *strcat(char *destination, const char *source);
功能说明
- 源字符串必须以’\0’结束
- 目标字符串也必须以’\0’结束,否则无法确定追加的起始位置
- 目标空间必须足够大,能容纳源字符串的内容
- 目标空间必须可修改
- 字符串不能自己给自己追加,会导致错误
模拟实现
char *my_strcat(char *dest, const char*src)
{char *ret = dest;assert(dest != NULL);assert(src != NULL);// 找到目标字符串的结束标志'\0'while(*dest){dest++;}// 追加源字符串while((*dest++ = *src++)){;}return ret;
}
六、strcmp函数:字符串比较
strcmp
函数用于比较两个字符串的大小,原型为:
int strcmp(const char *str1, const char *str2);
比较规则
- 从第一个字符开始比较,若相等则继续比较下一对字符,直到字符不同或遇到’\0’
- 标准规定:
- 第一个字符串大于第二个字符串,返回大于0的数字
- 两个字符串相等,返回0
- 第一个字符串小于第二个字符串,返回小于0的数字
- 比较的是对应位置字符的ASCII码值
模拟实现
int my_strcmp(const char *str1, const char *str2)
{assert(str1 != NULL);assert(str2 != NULL);while(*str1 == *str2){if(*str1 == '\0')return 0;str1++;str2++;}return *str1 - *str2;
}
七、strncpy函数:指定长度的字符串拷贝
strncpy
函数可以指定拷贝的字符个数,原型为:
char *strncpy(char *destination, const char *source, size_t num);
功能说明
- 拷贝
num
个字符从源字符串到目标空间 - 如果源字符串的长度小于
num
,则拷贝完源字符串后,在目标空间后追加0,直到达到num
个字符
八、strncat函数:指定长度的字符串追加
strncat
函数用于将源字符串的前num
个字符追加到目标字符串,原型为:
char *strncat(char *destination, const char *source, size_t num);
功能说明
- 将源字符串的前
num
个字符追加到目标字符串末尾,并追加一个’\0’ - 如果源字符串的长度小于
num
,则只追加到源字符串的’\0’为止
使用示例
#include <stdio.h>
#include <string.h>
int main ()
{char str1[20];char str2[20];strcpy(str1,"To be ");strcpy(str2,"or not to be");strncat(str1, str2, 6);printf("%s\n", str1); // 输出 "To be or not"return 0;
}
九、strncmp函数:指定长度的字符串比较
strncmp
函数用于比较两个字符串的前num
个字符,原型为:
int strncmp(const char *str1, const char *str2, size_t num);
功能说明
- 比较两个字符串的前
num
个字符 - 如果相等则继续比较,最多比较
num
个字符 - 如果提前发现不同,则提前结束比较
- 返回值规则与
strcmp
相同
返回值 | 说明 |
---|---|
<0 | 第一个不匹配的字符在str1中的值小于在str2中的值 |
0 | 两个字符串的前num个字符相等 |
>0 | 第一个不匹配的字符在str1中的值大于在str2中的值 |
十、strstr函数:查找子字符串
strstr
函数用于查找一个字符串在另一个字符串中第一次出现的位置,原型为:
char *strstr(const char *str1, const char *str2);
功能说明
- 返回字符串
str2
在字符串str1
中第一次出现的位置的指针 - 如果
str2
不是str1
的一部分,则返回空指针 - 匹配过程不包含’\0’,以’\0’作为结束标志
使用示例
#include <stdio.h>
#include <string.h>
int main ()
{char str[] = "This is a simple string";char *pch;pch = strstr(str, "simple");strncpy(pch, "sample", 6);printf("%s\n", str); // 输出 "This is a sample string"return 0;
}
模拟实现
char *strstr(const char *str1, const char *str2)
{char *cp = (char *)str1;char *s1, *s2;if (!*str2)return (char *)str1;while (*cp){s1 = cp;s2 = (char *)str2;while (*s1 && *s2 && !(*s1 - *s2)){s1++;s2++;}if (!*s2)return cp;cp++;}return NULL;
}
十一、strtok函数:字符串分割
strtok
函数用于分割字符串,原型为:
char *strtok(char *str, const char *sep);
功能说明
sep
参数是一个字符串,定义了用作分隔符的字符集合- 第一个参数为
str
时,函数找到str
中的第一个标记,并用’\0’结尾,返回指向该标记的指针,同时保存该位置 - 第一个参数为
NULL
时,函数从上次保存的位置继续查找下一个标记 - 如果没有更多标记,返回
NULL
strtok
会修改被操作的字符串,所以通常对字符串的临时拷贝进行操作
使用示例
#include <stdio.h>
#include <string.h>
int main()
{char arr[] = "192.168.6.111";char* sep = ".";char* str = NULL;for (str = strtok(arr, sep); str != NULL; str = strtok(NULL, sep)){printf("%s\n", str);}return 0;
}
// 输出:
// 192
// 168
// 6
// 111
十二、strerror函数:获取错误信息
strerror
函数用于获取错误码对应的错误信息,原型为:
char *strerror(int errnum);
功能说明
- 参数
errnum
为错误码,函数返回该错误码对应的错误信息字符串的地址 - 错误码通常定义在
errno.h
头文件中 - 程序启动时,
errno
(记录当前错误码的变量)为0,表示没有错误 - 当标准库函数发生错误时,会将对应的错误码存入
errno
使用示例
- 打印0~10的错误码对应的信息
#include <errno.h>
#include <string.h>
#include <stdio.h>
int main()
{int i = 0;for (i = 0; i <= 10; i++) {printf("%s\n", strerror(i));}return 0;
}
在Windows11+VS2022环境下的输出如下:
No error
Operation not permitted
No such file or directory
No such process
Interrupted function call
Input/output error
No such device or address
Arg list too long
Exec format error
Bad file descriptor
No child processes
- 在文件操作中使用
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main ()
{FILE *pFile;pFile = fopen("unexist.ent", "r");if (pFile == NULL)printf("Error opening file unexist.ent: %s\n", strerror(errno));return 0;
}
// 输出:Error opening file unexist.ent: No such file or directory
相关函数:perror
perror
函数可以直接打印错误信息,它会先打印参数中的字符串,再打印一个冒号和空格,最后打印错误信息。
#include <stdio.h>
#include <errno.h>
int main ()
{FILE *pFile;pFile = fopen("unexist.ent", "r");if (pFile == NULL)perror("Error opening file unexist.ent");return 0;
}
// 输出:Error opening file unexist.ent: No such file or directory
本文详细介绍了C语言中常用的字符函数和字符串函数,包括它们的功能、使用方法和模拟实现。这些函数在日常编程中非常实用,掌握它们能帮助我们更高效地处理字符和字符串操作。在使用过程中,要注意各个函数的参数要求和返回值特点,避免出现不必要的错误。