当前位置:网站首页>[Cultivation of internal skills of string functions] strlen + strstr + strtok + strerror (3)
[Cultivation of internal skills of string functions] strlen + strstr + strtok + strerror (3)
2022-08-04 22:50:00 【Albert Edison】
文章目录
1. strlen - 求字符串长度
函数介绍
size_t strlen(const char* string);
1、字符串已经 \0
作为结束标志,strlen 函数返回的是在字符串中 \0
前面出现的字符个数(不包含 \0
).
2、参数指向的字符串必须要以 \0
结束.
3、注意函数的返回值为 size_t,也就是无符号的整型.
代码示例
#include <stdio.h>
int main()
{
int len = my_strlen("abcdef");
printf("%d\n", len);
return 0;
}
运行结果
模拟实现
计数器实现
代码示例
#include <stdio.h>
#include <assert.h>
int my_strlen(const char* str) {
assert(str);
int cnt = 0;
while (*str != '\0') {
cnt++;
str++;
}
return cnt;
}
int main()
{
char str[] = "abcdef";
int len = my_strlen(str);
printf("%d\n", len);
return 0;
}
assert 是断言,判断 str 是不是空指针;
运行结果
递归实现
代码示例
#include <stdio.h>
#include <assert.h>
int my_strlen(const char* str) {
assert(str);
if (*str) {
return 1 + my_strlen(str + 1);
}
else
return 0;
}
int main()
{
char str[] = "abcdef";
int len = my_strlen(str);
printf("%d\n", len);
return 0;
}
运行结果
指针实现
代码示例
#include <stdio.h>
#include <assert.h>
int my_strlen(const char* str) {
assert(str);
const char* start = str; //Record the address of the first element
while (*str != '\0') {
str++;
}
return str - start; //最后一个元素的地址 - 首元素地址 = 中间的元素个数
}
//升级版
int my_strlen(char *s)
{
char *p = s;
while(*p != ‘\0’ )
p++;
return p-s;
}
int main()
{
char str[] = "abcdef";
int len = my_strlen(str);
printf("%d\n", len);
return 0;
}
运行结果
2. strstr - 字符串查找
函数介绍
char* strstr(const char* str2, const char* str1);
strstr 函数可以在一个字符串(str1)中查找另一个字符串(str2);
如果 str2 存在于 str1 中,那么就返回 str2 在 str1 中第一次出现的起始位置;
如果在 str1 中找不到 str2,那么就返回 空指针(NULL).
它的第一个参数是 str1 的起始位置,第二个参数是 str2 的起始位置.
代码示例
Suppose we are in strings
"abcdefabcdef"
中查找字符串 `“bcd”
#include <stdio.h>
#include <string.h>
int main()
{
char str1[] = "abcdefabcdef";
char str2[] = "bcd";
char* ret = strstr(str1, str2);
if (NULL == ret) {
printf("找不到\n");
}
else {
printf("%s\n", ret);
}
return 0;
}
运行结果
strstr 函数的返回值是字符串"bcd"
在字符串"abcdefbcd"
The starting position of the first occurrence of the ,而不是出现几次就返回几个起始位置.
模拟实现
strstr The mock implementation of the function is relatively complex,During implementation we need to set 3 个指针变量来辅助实现函数功能.
cur 指针: 记录每次开始匹配时的起始位置,当从该位置开始匹配时就找到了目标字符串,便于返回目标字符串出现的起始位置;当从该位置开始没有匹配成功时,则从 cur++ 处开始下一次的匹配.
s1 和 s2 指针: 通过判断 s1 和 s2 指针解引用后是否相等来判断每个字符是否匹配成功,若成功,则指针后移比较下一对字符;若失败,s1 指针返回 cur 指针处,s2 指针返回待查找字符串的起始位置.
例如,在字符串 "abbbcdef"
中查找字符串 "bbc"
:
首先 s1 指向的元素为 a,s2 指向的元素为 b,此时 s1 与 s2 不相等
则 cur 指针后移,接着将 cur 指针赋值给 s1 指针,此时,s1 指向的元素为 b,s2 指向的元素为 b,则s1 与 s2 匹配成功
那么 cur 指针不动,s1 和 s2 指针后移继续比较,此时,s1 指向的元素为 b,s2 指向的元素为 b,则s1 与 s2 匹配成功
那么 cur 指针不动,s1 和 s2 指针后移继续比较,此时,s1 指向的元素为 b,s2 指向的元素为 c,则s1 与 s2 不相等
那么 cur 指针向后移一位,s1 返回 cur 指向的位置,s2 Returns the starting position of the string to be searched
Then start the next round of matching,直到当 s2 指向的内容为\0
时,便说明待查找字符串中的字符已经被找完,也说明了从当前 cur 位置开始匹配能够找到目标字符串,所以此时返回指针 cur 即可.
代码示例
#include <stdio.h>
char* my_strstr(const char* str, const char* substr) {
const char* s1 = str;
const char* s2 = substr;
const char* cur = str;
assert(str && substr);
if (*substr == '\0') {
return (char*)str;
}
while (*cur) {
s1 = cur;
s2 = substr;
//1. 如果 *s1=\0,Indicates that the searched string has been exhausted,不可能找到
//2. 如果 *s2=\0,Indicates that the string has been found
while ((*s1 != '\0') && (*s2 != '\0') && (*s1 == *s2)) {
s1++;
s2++;
}
if (*s2 == '\0') {
return (char*)cur;
}
cur++;
}
// 找不到的情况
return NULL;
}
int main()
{
char str1[] = "abbbcdef";
char str2[] = "bbc";
char* ret = my_strstr(str1, str2);
if (NULL == ret) {
printf("找不到\n");
}
else {
printf("%s\n", ret);
}
return 0;
}
运行结果
3. strtok - 字符串分割
函数介绍
char* strtok(char* str, const char* sep);
strtok Function A function that splits a string into many substrings by a given sequence of characters.
它的第一个参数 str is the first address of the string to be split;
第二个参数 sep is the first address of a string,The string is a collection of characters used as separators.
The return value is the first address of the found tag.
注意:
1、sep 参数是个字符串,定义了用作分隔符的字符集合
2、第一个参数指定一个字符串,它包含了 0 个或者多个由 sep 字符串中一个或者多个分隔符分割的标记.
3、strtok 函数找到 str 中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针.
(注:strtok 函数会改变被操作的字符串,所以在使用 strtok 函数切分的字符串一般都是临时拷贝的内容并且可修改.)
4、strtok 函数的第一个参数不为 NULL ,函数将找到 str 中第一个标记,strtok 函数将保存它在字符串中的位置.
5、strtok 函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记.
6、如果字符串中不存在更多的标记,则返回 NULL 指针.
代码示例
Suppose we want to string
"[email protected]"
以"@"
字符和"."
character split
int main()
{
const char* p = "@."; //分隔符的字符集合
char arr[] = "[email protected]"; //待分割字符串
char buf[50] = {
0 };
strcpy(buf, arr);//将数据拷贝一份使用,防止原数据被修改
char* str = NULL;
str = strtok(buf, p); //第一次传参需传入待分割字符串首地址
while (str != NULL) {
//说明还未分割完
printf("%s\n", str); //打印标记
str = strtok(NULL, p); //Split the same string,The second and subsequent first arguments are NULL
}
return 0;
}
运行结果
当 strtok When the function finds the first token,将其后的@
字符改为\0
and returns the first address of the first token,So we start with the returned address,When you start printing a string, it just prints out edisonchen,Call it a second time on that string strtok function will be from@
Start looking for the next token after the character.
4. strerror - 错误报告函数
函数介绍
char* strerror(int errnum);
strerror 函数可以把 错误码 Convert to the corresponding error message,返回错误信息对应字符串的起始地址.
代码示例
我们可以先来看一下,Just those error messages
#include <stdio.h>
#include <string.h>
int main()
{
int i = 0;
for (i = 0; i < 10; ++i) {
printf("%s\n", strerror(i));
}
return 0;
}
运行结果
But it is definitely impossible to print all the error codes in the actual process,举个栗子
fopen The function of the function is to open a file,When its execution is successful, it will return the first address of the open file,A null pointer is returned on failure(NULL).
Then we assume to use fopen 打开一个不存在的文件,然后用 strerror to display error messages
代码示例
#include<stdio.h>
#include<string.h>
#include<errno.h>
int main()
{
FILE* pf = fopen("test.txt", "r");
if (NULL == pf) {
//出错误的原因是什么
printf("%s\n", strerror(errno));
return 0;
}
//读文件
//...
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
运行结果
When we want to open a file that does not exist(test.txt)when you come to read,显然 fopen 函数会执行失败,于是 pf The pointer received is a null pointer(NULL);
当库函数使用的时候,如果发生错误,会把 errno 这个全局的错误变量设置为本次执行库函数产生的错误码;
errno 是 C 语言提供的一个全局变量,可以直接使用,放在 errno.h 文件中的.
5. 字符分类函数
如下表
tolower、toupper - 字符转换
这里以 tolower 和 toupper 为例,Not much else to explain
代码示例
大小写互相转换
#include <stdio.h>
#include <ctype.h>
int main()
{
char ch = 0;
ch = getchar();
if (islower(ch)) {
ch = toupper(ch);
}
else {
ch = tolower(ch);
}
printf("%c\n", ch);
return 0;
}
运行结果
大写转小写
小写转大写
代码示例
把 str 字符串转换成小写
#include <stdio.h>
#include <ctype.h>
int main()
{
int i = 0;
char str[] = "HELLO WORLD\n";
char c;
while (str[i])
{
c = str[i];
if (isupper(c)) {
c = tolower(c);
}
putchar(c);
i++;
}
return 0;
}
运行结果
. 总结
以上就是我们 C Character and string library functions commonly used in the language,其实理解起来不难,重要是多加使用练习
边栏推荐
- promise详解
- 养殖虚拟仿真软件提供高沉浸式的虚拟场景互动操作体验学习
- 一点点读懂cpufreq(一)
- 【论文笔记KDD2021】MixGCF: An Improved Training Method for Graph Neural Network-based Recommender Systems
- BUG | The interface returns abnormal data
- To Offer | 03. Repeat Numbers in the array
- 智慧养老整体解决方案
- Nacos配置中心之客户端长轮询
- the warmest home
- Reconfigure the ffmpeg plugin in chrome
猜你喜欢
随机推荐
深度学习 RNN架构解析
【3D建模制作技巧分享】ZBrush纹理贴图怎么导入
【2020】【论文笔记】超表面:多功能和可编程——
temp7777
VC bmp文件总结
备战9月,美团50道软件测试经典面试题及答案汇总
使用代理对象执行实现类目标方法异常
【云原生 · Kubernetes】Kubernetes运维
Using ngrok to optimize web pages on raspberry pi (2)
边缘检测——(纯享版)
【3D建模制作技巧分享】如何使用ZBrush导出效果图
Detailed usage of LocalDateTime
养殖虚拟仿真软件提供高沉浸式的虚拟场景互动操作体验学习
SRv6网络的安全解决方案
【3D建模制作技巧分享】ZBrush如何设置笔刷快捷键
被领导拒绝涨薪申请,跳槽后怒涨9.5K,这是我的心路历程
ANT1.7下载以及配置方法
I was rejected by the leader for a salary increase, and my anger rose by 9.5K after switching jobs. This is my mental journey
If you can't get your heart, use "distributed lock" to lock your people
【3D建模制作技巧分享】ZBrush模型如何添加不同材质