目录
在编程的过程中,我们经常要处理字符和字符串,为了方便操作字符和字符串,C语言标准库中提供了一系列库函数。
1、字符分类函数
C语言中有一系列的函数是专门做字符分类的,也就是一个字符是属于什么类型的字符的。这些函数的使用都需要包含一个头文件是: ctype.h。
这些函数的使用方法非常类似,以 islower 函数为例,islower 用于判断参数部分的 c 是否是小写字母,如果是就返回非0的整数,如果不是则返回0。
int islower ( int c );
注意:虽然 islower 是判断字符的函数,但是传参却是整型,会将字符的ASCII码值传到函数。
例:将字符串中的小写字母转大写,其他字符不变。
2、字符转换函数
在C语言中,可以使用以下函数来进行字符转换:
① toupper():将小写字母转换为大写字母。
char toupper(char c);
② tolower():将大写字母转换为小写字母。
char tolower(char c);
这两个函数都接受一个字符作为参数,并返回相应的大小写转换后的字符。这些函数可以帮助您在C程序中进行字符的大小写转换操作。
3、strlen的使用和模拟实现
3.1 strlen 函数
strlen函数是C语言和C++语言中常用的字符串处理函数之一,用于计算字符串的长度,即字符串中的字符个数(不包括末尾的空字符'\0'),其对应的头文件 #include <string.h>,格式如下:
size_t strlen(const char *str);
strlen函数用于计算以空字符结尾的字符串的长度,即从字符串的起始位置开始计算,直到遇到空字符('\0')为止。最终返回的数值类型是无符号整型。所以要注意:
所以如果想让上述代码进行正确的判断,可以对输出结果进行强制类型转换再进行运算:
(int)strlen("abc")-(int)strlen("abcdef")
3.2 strlen函数的模拟实现
前面深入理解c指针系列详细讲解了指针的操作方式,就不再赘述。
三种不同方式的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;
else
return 1 + my_strlen(str + 1);
}
//指针-指针的⽅式
int my_strlen(char* s)
{
assert(str);
char* p = s;
while (*p != ‘\0’)
p++;
return p - s;
}
4、strcpy的使用和模拟实现
4.1 strcpy函数
strcpy
函数是C语言和C++语言中常用的字符串处理函数之一,用于将一个字符串复制到另一个字符串中,其对应头文件为#include<stdio.h>。下面是关于strcpy
函数的详细讲解:
char* strcpy(char * destination, const char * source );
destination
:目标字符串,即要将源字符串复制到的位置。source
:源字符串,即要被复制的字符串。
函数最终返回目标字符串 destination
的地址。strcpy
函数用于将源字符串source
复制到目标字符串 destination
中,直到遇到源字符串的结束符\0
(空字符)为止,包括结束符\0
。
注:上面说过strcpy函数复制字符串直到遇到源字符串的结束符\0
(空字符)为止,同时把\0也复制过去,所以源字符串结尾必须要有 ' \0'。
4.2 strcpy函数使用
在4.1中将一个字符串通过strcpy函数拷贝到了一个空字符数组中,但是如果是两个字符串该如何操作?
#include <stdio.h>
#include <string.h>
int main() {
char dest[20] = "Hello, ";
//const char* src = "World!";
char src[] = "World!";
printf("Before copying: %s\n", dest); // 输出:Before copying: Hello,
strcpy(dest, src); // 将源字符串复制到目标字符串的中间位置
printf("After copying: %s\n", dest); // 输出:After copying: Hello, World!
return 0;
}
如上代码,在strcpy函数里直接将两个字符串首地址传给函数,可以看到源字符串直接给目标字符串覆盖掉了。因为如果直接将目标字符串名字dest传参,其默认从首地址开始。所以,如果想将源字符串拷贝到目标字符串的某个位置,需要将参数写成 strcpy(dest + i,src),这样将源字符串拷贝到指定位置,同时覆盖到目标字符串中的 '\0'。
4.3 strcpy函数的模拟实现
5、strcat的使用和模拟实现
5.1 strcat函数及使用
strcat
函数用于将一个字符串(源字符串)追加到另一个字符串(目标字符串)的末尾,最终返回目标字符串的首地址。dest
:目标字符串,即要将源字符串追加到的位置, src
:源字符串,即要被追加的字符串
char *strcat(char *dest, const char *src);
①strcat
函数将源字符串src
追加到目标字符串dest
的末尾,直到遇到源字符串的结束符\0
(空字符)为止,包括结束符\0
。
②目标字符串dest
必须有足够的空间来容纳源字符串src
的内容以及两个字符串的连接后的结果。
5.2 strcat函数的模拟实现
#include <stdio.h>
#include <string.h>
#include<assert.h>
char* my_strcat(char* dest,const char* src)
{
char* ret = dest;
assert(dest && src);
//找到目标空间的'\0'
while (*dest)
{
dest++;
}
//拷贝
while (*dest++ = *src++)
{
;
}
return ret;
}
int main()
{
char arr1[20]="hello,";
char arr2[] = "world";
my_strcat(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
6、strcmp的使用和模拟实现
6.1 strcmp函数及使用
strcmp
函数是C语言中用于比较两个字符串大小的函数,其原型定义在string.h
头文件中。该函数用于按字典顺序(即ASCII码值)比较两个字符串,并返回一个整数值来表示比较结果。原型如下:
int strcmp(const char *str1, const char *str2);
函数接受两个参数,分别是指向要比较的字符串的指针str1
和str2
。它们分别指向以null结尾的C字符串(即以null字符\0
作为字符串的结束标志)。
只要记住:
1.这个函数比较的是两个字符串对应位置元素的ASCII码值,如果str1
对应元素的ASCII码值在str2
对应元素之前,则返回一个负整数,在其之后返回正整数,如果相等,则比较下一个元素。
2.该函数是对字符串元素依次进行比较,如果相等则比较下一个,一旦发现不相等的字符就能确定两个字符串的大小关系,后面的元素就不比较了。
3.如果两个字符串长度不相等,且前几个元素ASCII码值相同,那么短的比长的小。(如果短的是第一个字符串则返回负数,如果短的是第二个字符串则返回正数)
6.2 strcmp函数的模拟实现
//方法一
#include <stdio.h>
#include <string.h>
int my_strcmp(const char* s1, const char* s2)
{
while (*s1 == *s2)
{
if (*s1 == '\0')
return 0;
s1++;
s2++;
}
if (*s1 > *s2)
return 1;
else
return -1;
}
int main()
{
int ret = my_strcmp("dsads", "dsads");
if (ret > 0)
printf("大于");
else if (ret == 0)
printf("等于");
else
printf("小于");
return 0;
}
//方法二
int my_strcmp(const char* str1, const char* str2)
{
int ret = 0;
assert(src != NULL);
assert(dest != NULL);
while (*str1 == *str2)
{
if (*str1 == '\0')
return 0;
str1++;
str2++;
}
return *str1 - *str2;
}
7、strncpy函数的使用
strncpy
函数用于将指定长度的字符从一个字符串复制到另一个字符串,或者将指定长度的字符复制到目标字符串中,最终返回目标字符串的首字符地址。
char *strncpy(char *dest, const char *src, size_t n);
dest
:目标字符串,即要将源字符串复制到的位置。src
:源字符串,即要被复制的字符串。n
:要复制的字符个数,即最多复制的字符数。
strncpy
函数将源字符串src
中的最多n
个字符复制到目标字符串dest
中,不包括字符串结束符\0
(空字符)。- 如果源字符串
src
的长度小于n
,则复制完源字符串后,目标字符串dest
的剩余部分将用空字符\0
填充。 - 如果源字符串
src
的长度大于等于n
,则复制前n
个字符到目标字符串dest
中。
8、strncat函数的使用
strncat函数将 source 指向字符串的前 num 个字符追加到 destination 指向的字符串末尾,再追加⼀个 \0 字符,最终返回destination函数首字符地址。
char * strncat ( char * destination, const char * source, size_t num );
destination
:目标字符串,即要将源字符串连接到其末尾的字符串。source
:源字符串,即要被连接的字符串。num
:要连接的最大字符数。
strncat
函数将源字符串 source中的最多 n
个字符连接到目标字符串destination
的末尾,如果source指向的字符串的长度小于num的时候,只会将字符串中到 \0 的内容追加到destination指向的字符串末尾。连接完成后,目标字符串destination
的末尾会添加一个空字符\0
来确保字符串的结束。
#include <stdio.h>
#include <string.h>
int main() {
char dest[20] = "Hello, ";
const char *src = "World!";
strncat(dest, src, 3); // 将源字符串的前3个字符连接到目标字符串的末尾
printf("Concatenated string: %s\n", dest); // 输出:Concatenated string: Hello, Wor
return 0;
}
9、strncmp函数的使用
strncmp
函数是C语言中的字符串比较函数,用于比较两个字符串的前n个字符是否相等。
int strncmp ( const char * str1, const char * str2, size_t num );
str1
:要比较的第一个字符串。str2
:要比较的第二个字符串。num
:要比较的字符数。
如果两个字符串的前n个字符相等,则返回0。 如果两个字符串在前n个字符处不相等,则返回一个小于或大于0的整数。
strncmp
函数会逐个比较两个字符串中对应位置的字符,直到达到指定的字符数n,或者遇到不相等的字符。- 如果两个字符串的前n个字符都相等,或者n大于其中一个字符串的长度且两个字符串完全相等,则认为两个字符串相等。
- 比较时区分大小写,即大写字母和小写字母被认为是不同的字符。
#include <stdio.h>
#include <string.h>
int main()
{
const char *str1 = "Hello";
const char *str2 = "Help";
int result = strncmp(str1, str2, 3); // 比较两个字符串的前3个字符
if (result < 0)
{
printf("str1 is less than str2\n"); // 输出:str1 is less than str2
} else if (result > 0) {
printf("str1 is greater than str2\n");
} else {
printf("str1 is equal to str2\n");
}
return 0;
}
10、strstr的使用和模拟实现
10.1 strstr函数
strstr
函数是C语言中用于在一个字符串中查找指定子字符串的函数。
char *strstr(const char *haystack, const char *needle);
haystack
:要在其中查找子字符串的目标字符串。needle
:要查找的子字符串。
返回值:
- 如果在目标字符串
haystack
中找到子字符串needle
,则返回指向第一次出现子字符串的指针。 - 如果未找到子字符串,返回
NULL
。
功能:
strstr
函数在目标字符串haystack
中搜索子字符串needle
,并返回第一次出现子字符串的位置。- 搜索时会从目标字符串的开头开始逐个字符比较,直到找到完全匹配的子字符串或遍历完整个目标字符串
#include <stdio.h>
#include <string.h>
int main()
{
char arr1[]="abcdefhlhlk";
char arr2[] = "fds";
char* ret = strstr(arr1, arr2);
if(ret!=NULL)
printf("%s\n", ret);
else
printf("找不到");
return 0;
}
10.2 strstr函数的模拟实现
#include <stdio.h>
#include <string.h>
#include<assert.h>
char* my_strstr(char* str1, char* str2)
{
char* cur = str1;
char* s1 = NULL;
char* s2 = NULL;
assert(str1 && str2);
if (*str2 == '\0')
{
return str1;
}
while (*cur)
{
s1 = cur;
s2 = str2;
while (*s1 && *s2 && *s1 == *s2)
{
s1++;
s2++;
}
if (*s2 =='\0')
{
return (char*)cur;
}
cur++;
}
return NULL;
}
int main()
{
char arr1[]="abcdefhlhlk";
char arr2[] = "bcd";
char* ret = my_strstr(arr1, arr2);
if(ret!=NULL)
printf("%s\n", ret);
else
printf("找不到");
return 0;
}
11、strtok函数的使用
strtok
函数是C语言中用于将字符串分割成多个子字符串的函数。
char *strtok(char *str, const char *delimiters);
函数参数:
str
:要进行分割的字符串,第一次调用时传入非空字符串,后续调用传入NULL
。delimiters
:用于分割字符串的分隔符字符串,可以包含一个或多个字符。
返回值:
- 如果成功找到了下一个子字符串,则返回指向该子字符串的指针。
- 如果已经没有更多子字符串可供分割,则返回
NULL
。
功能:
strtok
函数在第一次调用时,将指定的字符串按照分隔符进行第一次分割。- 后续调用
strtok
函数(传入NULL
)会继续从上一次分割位置开始,将剩余部分按照分隔符进行分割。
strtok
函数会修改输入的字符串,将分隔符替换为\0
(空字符),因此在使用该函数之后,原始字符串会被改变。- 当需要分割多个字符串时,可以使用循环调用
strtok
函数,每次传入NULL
作为第一个参数,直到返回NULL
为止。 - 分隔符字符串中的每个字符都被视为一个独立的分隔符。例如,如果
delimiters
为","
,则逗号和句点都会被视为分隔符。
12、strerror函数的使用
12.1 sterror函数
char *strerror(int errnum);
函数参数:
errnum
:表示错误码的整数值,通常是在发生系统调用错误时返回的错误码。
返回值:
- 返回一个指向描述错误信息的字符串的指针。
功能:
strerror
函数接受一个整数错误码,并返回一个描述该错误码的字符串。- 错误信息字符串通常是与特定错误码相关联的人类可读的描述,可以帮助开发人员了解错误的具体原因。
下面的示例中,我们尝试打开一个不存在的文件,并通过errno
获取错误码,然后使用strerror
函数将错误码转换为错误信息字符串进行打印。
12.2 perror函数
perror
函数是一个C标准库中用于打印描述错误信息的函数。
void perror(const char *s);
函数参数:
s
:用于指定错误信息前缀的字符串,通常是自定义的错误提示信息。
功能:
perror
函数会将当前的错误码(存储在errno
中)所对应的错误信息字符串打印到标准错误输出流(stderr
)上。- 可以通过传入自定义的前缀字符串
s
来在错误信息前添加额外的描述性信息。
#include <stdio.h>
#include <errno.h>
int main()
{
FILE *file = fopen("nonexistentfile.txt", "r");
if (file == NULL)
{
perror("Error opening file");
}
return 0;
}
可以发现,
perror("Error opening file unexist.ent");
等价于
printf ("Error opening file unexist.ent: %s\n", strerror(errno));