当前位置:网站首页>【C语言】字符串函数
【C语言】字符串函数
2022-07-07 16:14:00 【平凡的人1】
作者:@平凡的人1
专栏:《C语言从0到1》
一句话:凡是过往,皆为序章
说明: 过去无可挽回, 未来可以改变
前面我们学习了4个函数——strlen\strcpy\strcat\strcmp,这些函数的长度都是不受限制的,今天,我们自然是要介绍一些其他的函数。内容可能相对来说比较多。
长度受限制的字符串函数
strncpy
char * strncpy ( char * destination, const char * source, size_t num );
- Copies the first num characters of source to destination. If the end of the source C string (which is signaled by a null-character) is found before num characters have been copied, destination is padded with zeros until a total of num characters have been written to it.
- 拷贝num个字符从源字符串到目标空间。
- 如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。
下面,我们来简单测试一下:
#include <stdio.h>
#include <string.h>
int main()
{
char arr1[20] = "abcdef";
char arr2[] = "hello world";
strncpy(arr1, arr2, 5);
printf("%s\n", arr1);
return 0;
}
运行:
我们来看看上面的第3点:
#include <stdio.h>
#include <string.h>
int main()
{
char arr1[20] = "abcdef";
char arr2[] = "ghi";
strncpy(arr1, arr2, 5);//arr2只有3个这里却要拷贝5个,这是怎么一回事呢
printf("%s\n", arr1);
return 0;
}
F10调试看看还没拷贝前arr1和arr2是这样子的:
拷贝完成之后呢?
我们可以清楚的看到,内容不够时会用’\0’来补充!
strncat
char * strncat ( char * destination, const char * source, size_t num );
- Appends the first num characters of source to destination, plus a terminating null-character.
- If the length of the C string in source is less than num, only the content up to the terminating null-character is copied.
#include <stdio.h>
#include <string.h>
int main()
{
char arr1[20] = "hello\0xxxxx";
printf("%s\n", arr1);
char arr2[] = "world";
strncat(arr1, arr2, 3);
printf("%s\n", arr1);
return 0;
}
结果我们都是知道的,那过程是什么样子的呢?我们不妨调试来看一看:追加之前:
追加后:
我们可以清楚的看到,会在最后面自动加上一个’\0’
那如果追加的长度大于本身呢?会不会像strncpy一样却多少就补多少个’\0’呢?测试一段代码:
#include <stdio.h>
#include <string.h>
int main()
{
char arr1[20] = "hello\0xxxxx";
printf("%s\n", arr1);
char arr2[] = "abc";
strncat(arr1, arr2, 6);
printf("%s\n", arr1);
return 0;
}
追加前:
追加后:
答案是并没有,只会添加一个’\0’。通过简单的分析,我们也大概知道了strncat的原理。
strncmp
int strncmp ( const char * str1, const char * str2, size_t num );
比较到出现另个字符不一样或者一个字符串结束或者num个字符全部比较完。
#include <stdio.h>
#include <string.h>
int main()
{
char arr1[] = "abcdef";
char arr2[] = "abc";
int ret = strncmp(arr1, arr2, 4);
printf("%d\n", ret);
if (ret == 0)
{
printf("==\n");
}
else if (ret < 0)
{
printf("<\n");
}
else
{
printf(">\n");
}
return 0;
}
实际上,这些函数多了个n也就多了长度限制,并没有多大的区别,长度受限的字符串函数使得代码更加严谨一些,我们尽可能去使用。
字符串查找
strstr
char * strstr ( const char *str1, const char * str2);
Returns a pointer to the first occurrence of str2 in str1, or a null pointer if str2 is not part of str1.
简单理解,这个函数就是查找子串的函数
#include <stdio.h>
#include <string.h>
int main()
{
char email[] = "[email protected]";
char substr[] = "eichang";
char*ret = strstr(email, substr);
if (ret == NULL)
{
printf("子串不存在\n");
}
else
{
printf("%s\n", ret);
}
return 0;
}
关于怎么使用并不是重点,重点是我们怎么去进行模拟实现!
strstr的模拟实现
我们先来说一说查找的过程:
可以分为两种情况来说明:
一种是简单的情况:一次匹配就能找到
另一种是比较复杂的情况:第一次匹配没有找到,需要记录当前的位置,继续匹配下去,需要找多次才能找到
下面进行简单的模拟实现:
#include <assert.h>
#include <stdio.h>
char*my_strstr(const char*str1,const char*str2)
{
assert(str1 && str2);
const char* s1 = str1;
const char* s2 = str2;
const char* p = str1;
while (*p)
{
s1 = p;
s2 = str2;
while (*s1!='\0'&&*s2!='\0'&&* s1 == *s2)
{
s1++;
s2++;
}
if (*s2 == '\0')
{
return (char*)p;
}
p++;
}
return NULL;
}
int main()
{
char email[] = "[email protected]";
char substr[] = "eichang";
//char*ret = strstr(email, substr);
char* ret = my_strstr(email, substr);
if (ret == NULL)
{
printf("子串不存在\n");
}
else
{
printf("%s\n", ret);
}
return 0;
}
找子串这里可以用KMP算法来进行实现,不过较为复杂,就不展开说明了。
strtok
char * strtok ( char * str, const char * sep );
sep参数是个字符串,定义了用作分隔符的字符集合
第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标 记。
strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注: strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容 并且可修改。)
strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串 中的位置。
strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标 记。
如果字符串中不存在更多的标记,则返回 NULL 指针.
我觉得这是一个比较奇怪的函数,不过并不妨碍我们认识它切割字符串
#include <stdio.h>
#include <string.h>
int main()
{
const char* sep = "@.";
char email[] = "[email protected]";
char cp[30] = {
0 };
strcpy(cp, email);
char*ret = strtok(cp, sep);
printf("%s\n", ret);
ret = strtok(NULL, sep);
printf("%s\n", ret);
ret = strtok(NULL, sep);
printf("%s\n", ret);
return 0;
}
怎么和for循环联系起来
#include <stdio.h>
#include <string.h>
int main()
{
const char* sep = "@.";
char email[] = "[email protected]";
char cp[30] = {
0 };
strcpy(cp, email);
char* ret = NULL;
for (ret = strtok(cp, sep); ret != NULL; ret = strtok(NULL, sep))
{
printf("%s\n", ret);
}
return 0;
}
错误信息报告
strerror
char * strerror ( int errnum );
返回错误码,所对应的错误信息。
#include <stdio.h>
#include <string.h>
int main()
{
printf("%s\n", strerror(0));
printf("%s\n", strerror(1));
printf("%s\n", strerror(2));
printf("%s\n", strerror(3));
printf("%s\n", strerror(4));
printf("%s\n", strerror(5));
}
这些并不需要我们记住,error-C语言设置的一个全局的错误码存放的变量
举个例子:
#include <stdio.h>
#include <string.h>
int main()
{
FILE* pf = fopen("test.txt", "r");
if (pf == NULL)
{
printf("%s\n", strerror(errno));
return 1;
}
else
{
}
return 0;
}
字符分类函数
这些函数是比较多的,零零散散,并不 一一举例子说明了,在这里,大家可以认识认识并自己动手实践一下:
函数 如果他的参数符合下列条件就返回真
iscntrl 任何控制字符
isspace 空白字符:空格‘ ’,换页‘\f’,换行’\n’,回车‘\r’,制表符’\t’或者垂直制表符’\v’
isdigit 十进制数字 0~9 isxdigit 十六进制数字,包括所有十进制数字,小写字母af,大写字母AF
islower 小写字母a~z
isupper 大写字母A~Z
isalpha 字母az或AZ
isalnum 字母或者数字,az,AZ,0~9
ispunct 标点符号,任何不属于数字或者字母的图形字符(可打印)
isgraph 任何图形字符
isprint 任何可打字符,包括图形字符和空白字符
#include <stdio.h>
#include <ctype.h>
int main()
{
int i = 0;
char str[] = "Test String.\n";
char c;
while (str[i])
{
c = str[i];
if (isupper(c))
c = tolower(c);
putchar(c);
i++;
}
return 0;
}
边栏推荐
- [trusted computing] Lesson 10: TPM password resource management (II)
- [principle and technology of network attack and Defense] Chapter 1: Introduction
- < code random recording two brushes> linked list
- Personal best practice demo sharing of enum + validation
- How to open an account for wealth securities? Is it safe to open a stock account through the link
- [network attack and defense principle and technology] Chapter 4: network scanning technology
- [distributed theory] (II) distributed storage
- 元宇宙带来的创意性改变
- 手机app外卖订餐个人中心页面
- 保证接口数据安全的10种方案
猜你喜欢
debian10系统问题总结
Easy to understand [linear regression of machine learning]
仿今日头条APP顶部点击可居中导航
原生js验证码
Download, installation and development environment construction of "harmonyos" deveco
Run Yolo v5-5.0 and report an error. If the sppf error cannot be found, solve it
[principle and technology of network attack and Defense] Chapter 6: Trojan horse
基于百度飞浆平台(EasyDL)设计的人脸识别考勤系统
Backup Alibaba cloud instance OSS browser
Yarn capacity scheduler (ultra detailed interpretation)
随机推荐
< code random recording two brushes> linked list
Tips of this week 135: test the contract instead of implementation
讨论| 坦白局,工业 AR 应用为什么难落地?
带动画的列表选中js特效
Import requirements in batches during Yolo training Txt
[principle and technology of network attack and Defense] Chapter 6: Trojan horse
[trusted computing] Lesson 12: TPM authorization and conversation
Tear the Nacos source code by hand (tear the client source code first)
Understanding of 12 methods of enterprise management
Cartoon | who is the first ide in the universe?
2021年全国平均工资出炉,你达标了吗?
mui侧边导航锚点定位js特效
线上比赛相关规则补充说明
Ansible 学习总结(9)—— Ansible 循环、条件判断、触发器、处理失败等任务控制使用总结
debian10系统问题总结
物联网OTA技术介绍
Five simple ways to troubleshoot with Stace
Mui side navigation anchor positioning JS special effect
Use onedns to perfectly solve the optimization problem of office network
Run Yolo v5-5.0 and report an error. If the sppf error cannot be found, solve it