这是我关于C语言中字符函数和字符串函数的一篇学习笔记,我将记录有关的知识点和重点
正文
1.字符分类函数
C语言提供了一系列字符分类函数,它们在使用时需要包含头文件 ctype.h
如以下代码,它会返回非零的值,如果参数不是小写字母,它会返回0
int ret = islower(a)
字符转换函数
C语言中有两个字符转换函数,分别为tolower函数和toupper函数,它们的功能分别是将大写字母转换为小写和将小写字母转换为大写
strlen函数
strlen函数用以计算字符串的长度,它会返回字符串中在’\0'之前的所有字符个数(不包含'\0')
size_t strlen ( const char * str );
注意:
strlen函数返回值类型为siz_t,无符号,且它在计算字符串长度时一遇到‘\0'就会结束
strlen函数的模拟实现
我采用了三种方式来实现strlen函数它们分别是:遍历字符串、指针相减和递归,下面的代码体现了这三种思路
#include<stdio.h>
//strlen函数模拟实现
//1.遍历字符串
//int my_strlen(char* arr)
//{
// int count = 0;
// while (*arr != '\0')
// {
// count++;
// arr++;
// }
// return count;
//}
//2.指针相减
//int my_strlen(char* arr)
//{
// int i = 0;
// char* arr1 = arr;
// while (*arr != '\0')
// {
// arr++;
// }
// return arr - arr1;
//}
//3.递归
int my_strlen(char* arr)
{
if (*arr == '\0')
{
return 0;
}
else
{
return 1 + my_strlen(arr + 1);
}
}
int main()
{
char arr[] = "ohhhhhhhhh";
int count = my_strlen(arr);
printf("%d", count);
return 0;
}
strcpy函数
strcpy函数用来将一个字符串的内容拷贝到另一个字符串中去
char* strcpy(char * destination, const char * source );
使用的时候要注意以下几点:
1.源字符串需要以'\0'结束
2.源字符串中的'\0'会被拷贝到目标空间
3.目标空间需要足够大,防止在拷贝时出现溢出的情况
4.目标空间不能是不可修改的
strcpy函数的模拟实现
void my_strcpy(char* arr, const char* arr1)
{
assert(arr);
assert(arr1);
while (*arr1 != '\0')
{
*arr++ = *arr1++;
}
*arr = *arr1;
}
int main()
{
char arr[] = "ohhhhh";
char arr1[] = "no";
my_strcpy(arr,arr1);
return 0;
}
strncpy函数
相较于strcpy函数,strncpy函数的安全性更高,它对比strcpy函数有以下优点:
1.引入了参数num控制拷贝的长度,防止了目标缓冲区溢出
2.strncpy函数会根据指定的拷贝长度增加'\0',而strcpy函数会一直拷贝源字符串直到遇到'\0'为止,这样可能会导致栈溢出
3.strncpy函数在源字符串长度小于目标缓冲区时会自动填充'\0',而strcpy函数则不会
总的来说strncpy函数能更安全地进行字符串拷贝,但在实际使用时要按需使用两个函数
char * strncpy ( char * destination, const char * source, size_t num );
strcat函数
strcat函数可以将一个字符串的内容追加到另一个字符串中
char* strcat(char*dest,const char*src)
使用注意以下几点:
1.源字符串要以‘\0’结束
2.目标字符串中也要有\0,便于知道追加位置
3.目标空间必须足够大,防止追加时发生溢出
4.目标空间必须可修改
5.字符串给自己追加,可能会导致潜在错误,因为这个函数会从目标字符串的终止符开始追加,但是字符串的长度并未改变,可能导致溢出,可以使用更安全的函数如strncat来达到目的
strcat函数模拟实现
char* my_strcat(char* arr,const char* arr1)
{
while (*arr != '\0')
{
arr++;
}
while (*arr++ = *arr1++);
}
int main()
{
char arr[20] = "ohhhhhhh ";
char arr1[] = "no";
my_strcat(arr,arr1);
return 0;
}
strncat函数
char* strncat(char* dest, const char* src, size_t n);
strncat函数增加了一个参数n来指定追加字符的长度,防止了目标缓冲区溢出,同时会根据指定的追加长度自动添加'\0',对于strcat来说,它只有遇到'\0'时才会停止,可能导致栈溢出
strcmp函数
int strcmp(const char* str1,const char* str2)
strcmp函数用于字符串之间的比较,按照字符的ASCII码值来判断大小,从而返回一个值
规定为:
第一个字符串大于第二个字符串,则返回大于0的值
第一个字符串小于第二个字符串,则返回小于0的值
第一个字符串等于第二个字符,则返回0
strcmp函数的模拟实现
#include<stdio.h>
#include<assert.h>
//模拟实现strcmp函数
int my_strcmp(const char* arr1, const char* arr2)
{
assert(arr1 != NULL);
assert(arr2 != NULL);
while (*arr1 == *arr2)
{
if (*arr1 == '\0' && *arr2 == '\0')
return 0;
arr1++;
arr2++;
}
return *arr1 - *arr2;
}
int main()
{
char arr1[] = "abcde";
char arr2[] = "abqd";
int ret = my_strcmp(arr1, arr2);
printf("%d", ret);
return 0;
}
strncmp函数
int strncmp ( const char * str1, const char * str2, size_t num );
strncmp函数增加了一个参数num用来控制需要比较的字符个数,最多比较num个字符,提前发现不一样就会提前结束,如果num个字符都相等,那么返回0
strstr函数
char * strstr ( const char * str1, const char * str2);
strstr函数用于在一个字符串中查找另外一个字符串,它返回str1中str2首次出现的指针,如果str2在str1中不存在,就返回空指针
strstr函数模拟实现
const char* my_strstr(const char* arr1, const char* arr2)
{
assert(arr1 != NULL);
if (arr2 == NULL)
{
return arr1;
}
while (*arr1 != '\0')
{
const char* fd1 = arr1;
const char* fd2 = arr2;
//可能相等的情况
if (*arr1 == *arr2)
{
while (*fd1 == *fd2)
{
fd1++;
fd2++;
//若相等,则返回指针
if (*fd2 == '\0')
return arr1;
}
}
arr1++;
}
//找不到返回空指针
return NULL;
}
int main()
{
char arr1[] = "abcabcd";
char arr2[] = "abcd";
const char* ret = my_strstr(arr1, arr2);
printf("%s", ret);
return 0;
}
strtok函数
char * strtok ( char * str, const char * sep);
strtok函数用于分割字符串,可以将一个字符串分割为多个子字符串,并返回第一个子字符串的指针
str:要分割的字符串的指针,第一次调用strtok时传入,之后传入NULL
sep:作为分隔符的字符串,其中任意一个字符都可以用来分割str中的子字符串
注意:
第一次调用strtok函数时必须传递需要分割的字符串的指针,在后续调用中将其设置为NULL
strtok函数会改变源字符串,并在分割位置插入\0字符,所以strtok一般用来切分临时拷贝且可修改的函数
在一次切分中,strtok函数会找到str中的一个标记,并用\0结尾,返回一个指向这个标记的指针,如果字符串中不存在更多标记,strtok函数会返回NULL指针
strerror函数
strerror函数可以返回参数部分错误码对应的错误信息的字符串地址
char* strerror(int errnum);
它的使用需要包含errno.h以及string.h两个头文件,C语言程序运行时会使用一个全局变量errno来记录程序的当前错误码,程序没有错误的时候errno为0,表示没有错误,errno的每一个错误码都对应了一个错误信息
下面我打印了errno每一个错误码对应的信息
完