字符和字符串的库函数C进阶
Posted 林慢慢i
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了字符和字符串的库函数C进阶相关的知识,希望对你有一定的参考价值。
前言:本章重点介绍字符和字符串的库函数使用,C语言本身是没有字符串类型的,字符串通常存放在常量字符串或字符数组中。字符串常量适用于那些对它不做修改的字符串函数。
文章目录
1.strlen
作用介绍:求字符串长度(不包含\\0)
程序1(自行判断下输出结果)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char* str1 = "abcdef";
char* str2 = "bbb";
printf("%d ", strlen(str1));
if (strlen(str2) - strlen(str1) > 0)
{
printf("str2>str1\\n");
}
else
{
printf("str1>str2\\n");
}
return 0;
}
输出:
模拟实现strlen
方式1(临时变量计数器方式):
int my_strlen(const char* str)
{
int count = 0;
while (*str)
{
count++;
str++;
}
return count;
}
方式2(不创建临时变量计数器):
int my_strlen(const char* str)
{
int count = 0;
while (*str)
{
count++;
str;
}
return count;
}
方式3(指针方式):
int my_strlen(const char* str)
{
char* p = str;
while (*p != '\\0')
{
p++;
}
return p - str;
}
2.strcpy
作用介绍:拷贝字符串
模拟实现
char* my_strcpy(char* dest, const* src)
{
char* ret = dest;
assert(dest != NULL);
assert(src != NULL);
while ((*dest = *src))
{
;
}
return ret;
}
3.strcmp
作用介绍:比较两个字符串是否相等,若字符相同则返回0
模拟实现
int my_strcmp(char* str1, char* str2)
{
assert(str1 && str2);
while (*str1 == *str2)//判断字符是否相等
{
if (*str2 == '\\0')//判断是否字符str2结束
{
return 0;
}
else
{
str1++;
str2++;
}
}
if (*str1 > *str2)
{
return 1;
}
if (*str1 < *str2)
{
return -1;
}
}
4.strcat
功能介绍:将source所指向的字符串追加到destination所指向的字符串后。
模拟实现
char* my_strcat(char* dest, const char* src)
{
assert(dest && src);
char* ret = dest;//用ret记录dest的首地址,方便后续返回
while (*dest != '\\0');
{
dest++;
}
while (*dest++ = *src++)//将src指向的字符串拷到dest后边
{
;
}
return ret;
}
5.strstr
功能介绍:判断str2是否在str1中出现,即str2是否为str1的子串,若是,则返回str2在str1中首次出现的字符地址,否则返回NULL。
案例:
int main()
{
char str1[] = "abbbcdef";
char str2[] = "bbc";
printf("%s", strstr(str1, str2));
return 0;
}
模拟实现
引入三个临时变量,下图中s1与s2就是我们分别指向进行比较的两个字符串(需要移动),首先比较判断s2是否与s1相同,cp用来记录当前比较的第一个字符的位置,遍历cp即可比较str2是否在str1中出现。
char* my_strstr(const char* str1, const char* str2)
{
assert(str1 && str2);
char* s1 = NULL;//不改变str1和str2的指向
char* s2 = NULL;//保留模式串str2
char* cp = (char*)str1;
while (*cp)//cp遍历str1
{
s1 = cp;
s2 = (char*)str2;
while (*s1 == *s2 && *s1 && *s2)
{
s1++;
s2++;
if (*s2 == '\\0')//s2遍历
return cp;
}
cp++;
}
return NULL;
}
6.strncpy
功能介绍:将source所指向的字符串中num个字符拷贝到destination所指向的字符串中。
模拟实现
char* my_strncpy(char* dest, const char* src, size_t num)
{
assert(dest && src);
char* cp = dest;
while (num && (*cp++ = *src++))//将src字符串中的num个字符拷贝到cp中
{
num--;
}
while (num)//若num人大于0,则将cp中接下来的num个字符置为'\\0'
{
*cp++ = '\\0';
num--;
}
return dest;
}
7.strncat
功能介绍:在destination所指向的字符串末尾加上num个source所指向的字符串的字符。
模拟实现
char* my_strncat(char* str1, const char* str2, size_t num)
{
assert(str1 && str2);
char* cp = str1;
while (*cp)//cp遍历str1至'\\0'
{
cp++;
}
while (num--)//将str2中num个字符拷贝到str1中,若num大于str2字符串长度,则将str1之后的一个字符置为'\\0'
{
*cp++ = *str2++;
if (*str2 == '\\0')
return str1;
}
*cp = '\\0';
return str1;
}
8.strncmp
模拟实现
int my_strncmp(const char* str1, const char* str2, size_t num)
{
assert(str1 && str2);
while (*str1 == *str2 && num)//str1与str2相等或num不为0是进入循环
{
str1++;
str2++;
num--;
if (*str2 == '\\0' || num == 0)//num等于0或str2与str1已比较完成说明二者相同,返回0
return 0;
}
if (*str1 > *str2)
return 1;
else
return -1;
}
9.strtok
功能介绍:
例子
int main()
{
char str[] = "150434346@qq.com";
char* sep = "@.";
char tmp[30];
char* cp = NULL;
strcpy(tmp, str);//将str拷贝一份到tmp中,避免strtok将str中的数据修改
for (cp = strtok(tmp, sep); cp; cp = strtok(NULL, sep))
{
printf("%s\\n", cp);
}
return 0;
}
10.strerror
功能介绍:返回错误码所对应的错误信息。
strerror函数的应用在判断一些操作的错误类型时能起到很好的效果,比如在程序未达到预期的效果时,可以通过strerror来判断错误的原因,比如:想打开text.txt文件时,没用达到预期效果,可以调用该函数来查找原因。
例子
#include <errno.h>
int main()
{
FILE* pFile;
pFile = fopen("unexist.ent", "r");
if (pFile == NULL)
printf("文件 不存在:%s\\n", strerror(errno));
return 0;
}
11.memcpy
功能介绍:
模拟实现
void* my_memcpy(void* dest, const void* src, size_t num)
{
void* ret = dest;
assert(dest && src);
while (num--)//4 3 2 1
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
return ret;
}
12.memcmp
功能介绍:
例子:
int main()
{
float arr1[] = { 1.0, 2.0,3.0,4.0 };
float arr2[] = { 1.0, 3.0 };
int ret = memcmp(arr1, arr2, 8);
//memcmp - strcmp
printf("%d\\n", ret);
return 0;
}
13.memmove
功能介绍:
测试例子
int main()
{
int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
memmove(arr1, arr1+2, 20);
return 0;
}
模拟实现
void* my_memmove(void* dest, const void*src, size_t num)
{
void* ret = dest;
assert(dest && src);
if (dest < src)
{
//前->后
while (num--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
}
else
{
//后->前
while (num--)//19
{
*((char*)dest + num) = *((char*)src + num);
}
}
return ret;
}
注释:memmove函数的模拟实现要小心指针所指向内容(数组)被覆盖的问题。
字符和字符串的库函数部分到此介绍结束了,感谢您的阅读!!!如果内容对你有帮助的话,记得给我三连(点赞、收藏、关注)——做个手有余香的人。
以上是关于字符和字符串的库函数C进阶的主要内容,如果未能解决你的问题,请参考以下文章