在许多的C语言题目中,需要知晓一个字符串的长度,如何对字符字母进行大小写转换,如何去拷贝一个字符串到另外一个字符串中,如何在一个字符串后连接另外一个字符串,等等;
C语言就为我们提供了一系列的库函数,简便了我们对字符与字符串的操作;
那么,本片章,就详细的将字符函数与字符串函数为大家提供理解与模仿实现。
对初学C语言的同志们来说,我感觉先为大家解决字符串函数,然后再对字符分类函数,字符转换函数进行讲解比较合适😂
字符串函数
对于下面部分字符串函数的使用,我们需要用到头文件<string.h>
1.strlen函数
原型:
size_t strlen ( const char * str )
说明:获取字符串长度:返回 C 字符串 str 的长度
C 字符串的长度由终止 null 字符确定:C 字符串的长度与字符串开头和终止字符('\0')之间的字符数一样长(不包括终止字符('\0')本身)。
这不应与保存字符串的数组的大小相混淆。例如:char mystr[100]=“test”;
定义一个大小为 100 个字符的字符数组,但初始化 mystr 的 C 字符串的长度只有 11 个字符。 (因为字符串末尾隐藏了'\0',即用数组表示为{ ' t ' , ' e ' , ' s ' , ' t ' , ' \0 ' },strlen函数遇到第一个'\0'便停止了访问)
因此,当 sizeof(mystr) 的计算结果为 100 时,strlen(mystr) 返回 4。
示例:
#include<stdio.h>
#include<string.h>
int main()
{
char arr[30] = "abcd\0efg\0hi";
size_t ret = strlen(arr);
printf("%d\n", ret);
return 0;
}
运行结果:
模仿实现:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
//#include<string.h>
#include<assert.h>
size_t my_strlen(const char* p)
{
assert(p != NULL);
size_t count = 0;
while (*p != '\0')
{
count++;
p++;
}
return count;
}
int main()
{
char arr[30] = "abcd\0efg\0hi";
//size_t ret = strlen(arr);
size_t ret = my_strlen(arr);
printf("%zd\n", ret);
return 0;
}
运行结果:
2.strcpy函数
原型:
char * strcpy ( char * destination, const char * source );
说明:复制字符串
将源指向的 C 字符串复制到目标指向的数组中,包括终止 null 字符(并在该点停止)。
为避免溢出,destination 指向的数组的大小应足够长,以包含与 source 相同的 C 字符串(包括终止 null 字符),并且不应在内存中与 source 重叠
示例:
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[] = "abcde";
char arr2[20] = { 0 };
strcpy(arr2, arr1);
printf("%s\n", arr2);
return 0;
}
运行结果:
模仿实现:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<assert.h>
char* my_strcpy(char* dest, const char* src)
{
assert(dest && src);
char* cur = dest;
while (*dest++ = *src++);
return cur;
}
int main()
{
char arr1[] = "abcde";
char arr2[20] = { 0 };
my_strcpy(arr2, arr1);
printf("%s\n", arr2);
return 0;
}
运行结果:
3.strcat函数
原型:
char * strcat ( char * destination, const char * source );
说明:连接字符串
将源字符串的副本追加到目标字符串。destination 中的终止 null 字符,即(' \0 ')被 source 的第一个字符覆盖,并且在 destination 中由两者串联形成的新字符串的末尾包含一个 null 字符
示例:
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[20] = "abcde";
char arr2[20] = "fghi";
strcat(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
运行结果:
模仿实现:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<assert.h>
char* my_strcat(char* dest, const char* src)
{
assert(dest && src);
char* cur = dest;
while (*dest != '\0')
{
dest++;
}
while (*dest++ = *src++);
return cur;
}
int main()
{
char arr1[20] = "abcde";
char arr2[20] = "fghi";
my_strcat(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
运行结果:
4.strcmp函数
原型:
int strcmp ( const char * str1, const char * str2 );
说明:比较两个字符串
将 C 字符串 str1 与 C 字符串 str2 进行比较。
若str1>str2,返回大于0的整数;
若str1<str2,返回小于0的整数;
若str1=str2,返回等于0的整数;
此函数开始比较每个字符串的第一个字符。如果它们彼此相等,则继续以下对,直到字符不同或达到终止字符(' \0 ')。
示例:
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[20] = "abcde";
char arr2[20] = "abbdefg";
int ret = strcmp(arr1, arr2);
printf("%d\n", ret);
return 0;
}
运行结果:
模仿实现:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<assert.h>
int my_strcmp(const char* str1, const char* str2)
{
int ret = 0;
assert(str1 && str2);
while (!(ret = *(unsigned char*)str2 - *(unsigned char*)str1) && *str1)
{
++str2, ++str1;
}
if (ret < 0)
ret = -1;
else if (ret > 0)
ret = 1;
return ret;
}
int main()
{
char arr1[20] = "abcde";
char arr2[20] = "abcceuuu";
int ret = my_strcmp(arr1, arr2);
printf("%d\n", ret);
return 0;
}
运行结果:
5.strstr函数
原型:
const char * strstr ( const char * str1, const char * str2 ); char * strstr ( char * str1, const char * str2 );
说明:查找子字符串
返回指向 str1 中 str2 第一次出现的指针,如果 str2 不是 str1 的一部分,则返回 null 指针。
匹配过程不包括终止 null 字符,但到此为止。
参数:
str1:要扫描的 C 字符串。
str2:包含要匹配的字符序列的 C 字符串。
返回值:指向 str2 中指定的整个字符序列的 str1 中第一个出现的指针,如果 str1 中不存在该序列,则为空指针。
示例:
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[] = "abcde";
char arr2[] = "bc";
const char*ret=strstr(arr1, arr2);
printf("%s\n", ret);
return 0;
}
运行结果:
模仿实现:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
char* my_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);
}
int main()
{
char arr1[] = "abcde";
char arr2[] = "bc";
const char*ret=my_strstr(arr1, arr2);
printf("%s\n", ret);
return 0;
}
运行结果:
下面的字符串函数是在2.3.4的基础上进行“升级的函数”
6.strncpy函数
原型:
char * strncpy ( char * destination, const char * source, size_t num );
说明:从字符串中复制字符
将源的前 num 个字符复制到目标。如果在复制 num 个字符之前找到source C 字符串(由 null 字符表示)的末尾,则 destination 将填充为零,直到总共写入 num 个字符。
如果 source 的长度大于 num,则不会在目标末尾隐式追加 null 字符。因此,在这种情况下,destination 不应被视为以 null 结尾的 C 字符串(这样读取它会溢出)。
destination和source不得重叠
示例:
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[] = "abcde";
char arr2[20] = { 0 };
strncpy(arr2, arr1, 3);
printf("%s\n", arr2);
return 0;
}
运行结果:
模仿实现:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<assert.h>
char* my_strncpy(char* dst, const char* src, size_t n)
{
assert(dst && src);
int i;
for (i = 0; src[i] && i < n; i++)
{
dst[i] = src[i];
}
if (i < n)
{
dst[i] = 0;
}
return dst;
}
int main()
{
char arr1[] = "abcde";
char arr2[20] = { 0 };
strncpy(arr2, arr1, 3);
printf("%s\n", arr2);
return 0;
}
运行结果:
7.strncat函数
原型:
char * strncat ( char * destination, const char * source, size_t num );
说明:从字符串中追加字符
将源的前 num 个字符附加到目标,以及终止 null 字符。
如果 source 中 C 字符串的长度小于 num,则仅复制直到终止 null 字符的内容。
示例:
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[20] = "abcde";
char arr2[] = "fghi";
strncat(arr1, arr2, 3);
printf("%s\n", arr1);
return 0;
}
运行结果:
模仿实现:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<assert.h>
char* my_strncat(char* dst, const char* src, size_t n)
{
assert(dst && src);
char* tmp = dst;
while (*dst)
{
dst++;
}
int i;
for (i = 0; src[i] && i < n; i++)
{
dst[i] = src[i];
}
dst[i] = 0;
return tmp;
}
int main()
{
char arr1[20] = "abcde";
char arr2[] = "fghi";
strncat(arr1, arr2, 3);
printf("%s\n", arr1);
return 0;
}
运行结果:
以上函数可解决许多问题,熟能生巧吧☺