当前位置:网站首页>【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;
}
边栏推荐
- 科学家首次观察到“电子漩涡” 有助于设计出更高效的电子产品
- 磁盘存储链式的B树与B+树
- 自动化测试:Robot FrameWork框架大家都想知道的实用技巧
- 【蓝桥杯集训100题】scratch从小到大排序 蓝桥杯scratch比赛专项预测编程题 集训模拟练习题第17题
- Afghan interim government security forces launched military operations against a hideout of the extremist organization "Islamic state"
- [principle and technology of network attack and Defense] Chapter 1: Introduction
- What skills can you master to be a "master tester" when doing software testing?
- 面试官:页面很卡的原因分析及解决方案?【测试面试题分享】
- 机器人工程终身学习和工作计划-2022-
- Live broadcast software construction, canvas Text Bold
猜你喜欢
Ansible learning summary (9) -- ansible loop, condition judgment, trigger, processing failure and other task control use summary
More than 10000 units were offline within ten days of listing, and the strength of Auchan Z6 products was highly praised
2021-06-28
[principle and technology of network attack and Defense] Chapter 6: Trojan horse
三仙归洞js小游戏源码
回归测试的分类
讨论| 坦白局,工业 AR 应用为什么难落地?
[answer] if the app is in the foreground, the activity will not be recycled?
Chapter 2 build CRM project development environment (database design)
Introduction to OTA technology of Internet of things
随机推荐
Test for 3 months, successful entry "byte", my interview experience summary
SD_DATA_SEND_SHIFT_REGISTER
Tear the Nacos source code by hand (tear the client source code first)
Introduction to OTA technology of Internet of things
Click on the top of today's headline app to navigate in the middle
js拉下帷幕js特效显示层
Tips of the week 136: unordered containers
财富证券证券怎么开户?通过链接办理股票开户安全吗
Vscode three configuration files about C language
Deep learning machine learning various data sets summary address
Slider plug-in for swiper left and right switching
现在网上期货开户安全吗?国内有多少家正规的期货公司?
磁盘存储链式的B树与B+树
[principle and technology of network attack and Defense] Chapter 6: Trojan horse
Chapter 2 building CRM project development environment (building development environment)
[trusted computing] Lesson 12: TPM authorization and conversation
仿今日头条APP顶部点击可居中导航
debian10编译安装mysql
[principles and technologies of network attack and Defense] Chapter 3: network reconnaissance technology
Chapter 3 business function development (user access project)