当前位置:网站首页>【C语言进阶11——字符和字符串函数及其模拟实现(2))】
【C语言进阶11——字符和字符串函数及其模拟实现(2))】
2022-04-23 18:51:00 【初学C语言者】
字符和字符串函数及其模拟实现(2)
前言
本文接着学习字符和字符串函数,并用代码模拟实现。主要学习内容包括:
4、 字符串查找
- strstr
- strtok
5、错误信息报告
- strerror
6、字符操作函数
7、内存操作函数
- memcpy
- memmove
- memset
- memcmp
4、字符串查找
4.1 库函数 strstr
char * strstr ( const char *str1, const char * str2);
- 返回指向str1中第一个出现的str2的指针,如果str2不是str1的一部分,则返回空指针
int main()
{
char a1[] = "abbbcdef";
char a2[] = "bbc";
char* ret = strstr(a1, a2);
if (NULL==ret)
{
printf("找不到子字串\n");
}
else
{
printf("%s\n", ret);
}
}
4.2 模拟实现库函数 strstr
char* my_strstr(const char* p1, const char* p2)
{
assert(p1&&p2);
const char* s1 = p1;//赋予指针初始位置
const char* s2 = p2;//赋予指针初始位置
const char* cur = p1;//记录字符串当前指针位置
while (*cur)
{
s1 = cur;
s2 = p2;//移到初始位置
while (*s1 && *s2 && (*s1==*s2))
{
s1++;//相等时,指针后移,直到两个不相等或者一方为0
s2++;
}
if (*s2=='\0')
{
return (char*)cur;
}
cur++;//不相等,当前指针加1
}
//跳出,就是字符串1移动到末尾
return NULL;
}
int main()
{
char a1[] = "abbbcdef";
char a2[] = "bbc";
char* ret = my_strstr(a1, a2);
if (NULL==ret)
{
printf("找不到子字串\n");
}
else
{
printf("%s\n", ret);
}
}
结果见下图:

4.3 库函数 strtok
char * strtok ( char * str, const char * sep );
- sep参数是个字符串,定义了用作分隔符的字符集合第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记
- strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针
- strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改
- strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置
- strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记
- 如果字符串中不存在更多的标记,则返回 NULL 指针
int main()
{
char a[] = "[email protected]@hello world";
char a2[50] = {
0 };
strcpy(a2, a);
printf("%s\n", a2);
const char* sep = "@. ";//三个分隔符
printf("%s\n", strtok(a2, sep));//learnC
printf("%s\n", strtok(NULL, sep));//day
printf("%s\n", strtok(NULL, sep));//day
return 0;
}
结果见下图:


int main()
{
char a[] = "[email protected]@hello world";
char a2[50] = {
0 };
strcpy(a2, a);
printf("%s\n", a2);
const char* sep = "@. ";//三个分隔符
char* str = NULL;
//用循环来查找多有的分隔符隔开的字符串,不为空,就找下一个,直到结束
for (str =strtok(a2,sep); str != NULL; str=strtok(NULL,sep))
{
printf("%s\n", str);
}
return 0;
}
结果见下图:

5、错误信息报告
5.1 库函数 strerror
char * strerror ( int errnum );
- 返回错误码,所对应的错误信息
int main()
{
int* p = (int*)malloc(INT_MAX);//在堆区申请内存
if (p==NULL)
{
printf("%s\n", strerror(errno));//打印出错信息
return 1;
}
return 0;
}
结果见下图:

6、字符操作函数
| 函数 | 如果他的参数符合下列条件就返回真 |
|---|---|
| iscntrl | 任何控制字符 |
| isspace | 空白字符:空格‘ ’,换页‘\f’,换行’\n’,回车‘\r’,制表符’\t’或者垂直制表符’\v’ |
| isdigit | 十进制数字 0~9 |
| isxdigit | 十六进制数字,包括所有十进制数字,小写字母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 | 任何可打印字符,包括图形字符和空白字符 |
7、内存操作函数
7.1 库函数 memcpy
void * memcpy ( void * destination, const void * source, size_t num );
- 函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置
- 这个函数在遇到 ‘\0’ 的时候并不会停下来
- 如果source和destination有任何的重叠,复制的结果都是未定义的
int main()
{
int a1[10] = {
1,2,3,4,5,6,7,8,9,10 };
int a2[5] = {
0 };
memcpy(a2, a1, 20);
int sz = sizeof(a1) / sizeof(a1[0]);
for (int i = 0; i < sz; i++)
{
printf("%d\n", a2[i]);
}
return 0;
}
7.2 模拟实现库函数 memcpy
//模拟实现
void* my_memcpy(void* dest, const void* src, size_t cnt)
{
assert(dest&&src);
void* ret = dest;//接收任何类型的数据
while (cnt--)
{
*(char*)dest = *(char*)src;//按字节顺序来交换
dest = (char*)dest + 1;
src = (char*)src + 1;
}
return ret;
}
int main()
{
int a1[10] = {
1,2,3,4,5,6,7,8,9,10 };
int a2[5] = {
0 };
my_memcpy(a2, a1, 20);
int sz = sizeof(a1) / sizeof(a1[0]);
for (int i = 0; i < sz; i++)
{
printf("%d\n", a2[i]);
}
return 0;
}
结果见下图:


7.3 库函数 memmove
void * memmove ( void * destination, const void * source, size_t num );
- 和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的
- 如果源空间和目标空间出现重叠,就得使用memmove函数处理
int main()
{
int a1[10] = {
1,2,3,4,5,6,7,8,9,10 };
memmove(a1+2, a1, 20);
int sz = sizeof(a1) / sizeof(a1[0]);
for (int i = 0; i < sz; i++)
{
printf("%d\n", a1[i]);
}
return 0;
}
7.4 模拟实现库函数 memmove
//模拟实现
void* my_memmove(void* dest, const void* src, size_t cnt)
{
assert(dest&&src);
void* ret = dest;
if (dest<src)
{
//从左往右拷贝
while (cnt--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
}
else
{
//从右往左
while (cnt--)
{
*((char*)dest + cnt) = *((char*)src + cnt);
}
}
return ret;
}
int main()
{
int a1[10] = {
1,2,3,4,5,6,7,8,9,10 };
my_memmove(a1+2, a1, 20);
int sz = sizeof(a1) / sizeof(a1[0]);
for (int i = 0; i < sz; i++)
{
printf("%d\n", a1[i]);
}
return 0;
}
结果见下图:

7.5 库函数 memcmp
int memcmp ( const void * ptr1, const void * ptr2, size_t num );
- 比较从ptr1和ptr2指针开始的num个字节
- 返回值小于0,前面字节的数据小于后面对应字节的数据
- 返回值等于0,前面字节的数据等于后面对应字节的数据
- 返回值大于0,前面字节的数据大于后面对应字节的数据
int main()
{
int a1[] = {
1,2,3,4,5 };
int a2[] = {
1,2,3,4,0x11223305 };
int ret = memcmp(a1, a2, 18);
printf("%d\n", ret);
return 0;
}
结果见下图:

7.6 库函数 memset
void *memset( void *dest, int c, size_t count );
- memset 函数将 目标空间 dest 的 总共 count 个字节内容设置为字符c。
int main()
{
int a[] = {
0x11111111,0x22222222,3,4,5 };
memset(a, 6, 20);
return 0;
}
结果见下图:

总结
字符串库函数的学习基本结束了。学完有点混乱,这块内容就当字典,需要的时候再来查。
感觉单独学字符串库函数有点枯燥,这个要后面刷题才能深刻的理解并掌握这些函数的用法。
库函数实现学习的眼花缭乱,还有一点内容没写完全,等以后再添加内容。
下一篇更新结构体相关的内容。
版权声明
本文为[初学C语言者]所创,转载请带上原文链接,感谢
https://blog.csdn.net/taibudong1991/article/details/124330870
边栏推荐
- Use bitnami / PostgreSQL repmgr image to quickly set up PostgreSQL ha
- Simple use of viewbinding
- Use of kotlin collaboration in the project
- Redis common interview questions
- K210 serial communication
- CISSP certified daily knowledge points (April 19, 2022)
- ctfshow-web361(SSTI)
- Tencent map and high logo removal method
- Dynamically add and delete layouts
- Advanced transfer learning
猜你喜欢

ESP32 LVGL8. 1 - roller rolling (roller 24)

Excel intercept text

MVVM模型

mysql_ Download and installation of Linux version

机器学习理论之(8):模型集成 Ensemble Learning

ESP32 LVGL8. 1. Detailed migration tutorial of m5stack + lvgl + IDF (27)

使用 bitnami/postgresql-repmgr 镜像快速设置 PostgreSQL HA

Chondroitin sulfate in vitreous

listener. log

Use stm32cube MX / stm32cube ide to generate FatFs code and operate SPI flash
随机推荐
The first leg of the national tour of shengteng AI developer creation and enjoyment day was successfully held in Xi'an
Query the logistics update quantity according to the express order number
K210 serial communication
解决:cnpm : 无法加载文件 ...\cnpm.ps1,因为在此系统上禁止运行脚本
STM32: LCD显示
机器学习理论基础篇--关于机器学习的一些术语
Esp32 (UART event) - serial port event learning (1)
12个例子夯实promise基础
Introduction to ROS learning notes (II)
Esp32 (UART ecoh) - serial port echo worm learning (2)
Solutions such as unknown or garbled code or certificate problem prompt in Charles's mobile phone packet capture, actual measurement.
Nacos作为服务配置中心实战
Configure iptables
Sentinel规则持久化进Nacos
机器学习理论之(7):核函数 Kernels —— 一种帮助 SVM 实现非线性化决策边界的方式
Golang 语言实现TCP UDP通信
机器学习理论之(8):模型集成 Ensemble Learning
ctfshow-web362(SSTI)
昇腾 AI 开发者创享日全国巡回首站在西安成功举行
The corresponding permissions required to automatically open the app in the setting interface through accessibility service