做网站公司-深圳信科,apache 创建网站,沈阳网 沈阳网站,网件路由器定时重启字符串函数 一.strlen#xff08;求字符串长度#xff09;1.函数使用2.模拟实现#xff08;三种方法#xff09; 二.strstr#xff08;字符串查找子串#xff09;1.函数使用2.模拟实现 三.strtok#xff08;字符串分割#xff09;四.strerror#xff0c;perror#x… 字符串函数 一.strlen求字符串长度1.函数使用2.模拟实现三种方法 二.strstr字符串查找子串1.函数使用2.模拟实现 三.strtok字符串分割四.strerrorperror打印错误信息 一.strlen求字符串长度
1.函数使用
size_t strlen(const char* str);strlen函数用于求字符串的长度参数是字符串的首地址返回值是无符号的整形初始化字符串有两种它们各自存在一些小的细节如下
#includestdio.h
#includestring.h
int main()
{char str1[] abcdef;//本质{ a,b,c,d,e,f,\0 };隐藏了\0在末尾char str2[] { a,b,c,d,e,f };//函数strlen() 求字符串长度printf(%zu\n, strlen(str1));//6printf(%zu\n, strlen(str2));//由于尾部没有\0随机数所以打印随机数printf(%s\n, str2);//直到找到\0为止停止打印//关键字sizeof()求字节的大小返回值同样是size_t(unsigned int)printf(%zu\n, sizeof(str1));//7printf(%zu\n, sizeof(str2));//6return 0;
}可以看到str2的长度居然是33其实这是因为strlen函数会从首地址指向的字符一直向后查找直到遇到’\0’才会停下不包含 ‘\0’ )统计’\0’之前出现的字符的个数而str2末尾没有’\0’所以会一直向后查找在某个位置恰好遇到了’\0’所以打印随机数33。printf函数打印字符串也是同样的道理看似传入abcdef其实真正传入的是首地址a的地址遇到了’\0’停止打印。那为什么会出现烫烫烫呢这就牵扯到了函数栈帧了日后会将函数栈帧更新上来。
总结 字符串以 ‘\0’ 作为结束标志strlen函数返回的是在字符串中 ‘\0’ 前⾯出现的字符个数不包 含 ‘\0’ )。 参数指向的字符串必须要以 ‘\0’ 结束。 注意函数的返回值为size_t是无符号整形size_t 等价于 unsigned int。
易错点
#includestdio.h
int main()
{if (strlen(abc) - strlen(abcdef))printf(\n);elseprintf(\n);return 0;
}我们会发现输出的居然大于号这是因为strlen函数的返回值是无符号的整形而无符号的整形相减仍然得到无符号的整形而-3按照无符号整形来说是一个很大的数自然打印大于号。
如图
也可以这么写
#includestdio.h
int main()
{//if ((int)strlen(abc) - (int)strlen(abcdef) 0)if (strlen(abc) strlen(abcdef))printf(\n);elseprintf(\n);return 0;
}2.模拟实现三种方法
方法一计数器方法我们定义一个变量为count如果传入的指针指向的内容不是’\0’那么count同时指针后移一位循环往复直到找到’\0’时返回count即可。
#includeassert.h
size_t my_strlen(const char* str)
{assert(str ! NULL);//断言若str为NULL报错头文件assert.hsize_t count 0;while (*str ! \0){str;count;}return count;
}方法二指针减指针我们先定义两个指针变量start与end将传入的指针保存下来然后将指针end向后移直到遇到’\0’时我们返回指针end与指针start的差值即可。指针与指针的差的绝对值是两个指针之间的元素个数。
#includeassert.h
size_t my_strlen(const char* str)
{assert(str ! NULL);//断言若str为NULL报错头文件assert.hconst char* start str;const char* end str;while (*end ! \0){end;}return end - start;
}方法三递归判断传入指针指向的内容是否为’\0’如果是就返回0不是就返回my_strlen2(str1)1如此进行下去直到递归到内层时找到’\0’这时再一步步将值返回回来即可。
#includeassert.h
size_t my_strlen(const char* str)
{assert(str ! NULL);//断言若str为NULL报错头文件assert.hif (*str \0)return 0;elsereturn my_strlen(str 1) 1;
}二.strstr字符串查找子串
1.函数使用
char* strstr(const char* str1, const char* str2)strstr函数用于在字符串 str1 中查找另一个字符串 str2如果字符串 str1 存在字符串 str2那么就返回字符串 str2 在字符串 str1 中第一次出现的起始位置如果找不到那么就返回空指针(NULL)。它的第一个参数是字符串 str1 的首地址第二个参数是字符串 str2 的首地址。若字符串 str2 为空字符串则返回字符串 str1 的首地址。
#includestdio.h
#includestring.h
int main()
{char arr1[] ABCDEFG;char arr2[] CDE;char* ret strstr(arr1, arr2);//返回arr1中字符C的地址if (ret ! NULL)printf(%s\n, ret);//打印CDEFGelseprintf(子串不存在\n);return 0;
}2.模拟实现
例如在字符串abbbcdef中查找字符串bbc
p指针 记录每次开始匹配时的起始位置当从该位置开始匹配时就找到了目标字符串便于返回指针p当从该位置开始没有匹配成功时则指针p后移一位进行下一次的匹配。s1和s2指针 通过判断s1和s2指针解引用后是否相等来判断单个字符是否匹配成功。若成功则指针s1与s2后移一位比较下一对字符若失败指针p后移一位指针s1返回指针p处指针s2返回待查找字符串的起始位置。
如图 代码实现
#includeassert.h
#includestdio.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;if (*str2 \0)//要查找的字符串为空字符串{return str1;}while(*p ! \0)//若要减少循环数则可以修改为//while ((p - str1) (int)strlen(str1) - (int)strlen(str2)){while (*s1 *s2 *s1 ! \0 *s2 ! \0){s1;s2;}if(*s2\0)//字符串查找子串成功{return p;}p;s1 p;s2 str2;}return NULL;//找不到目标字符串返回NULL
}
int main()
{char arr1[] abbbcdef;char arr2[] bbc;char* ret my_strstr(arr1, arr2);if (ret ! NULL)printf(%s\n, ret);elseprintf(子串不存在\n);return 0;
}对于以上代码对于循环次数还可以优化下比如待比较的字符串str2长度大于字符串str1还能比较的字符的个数时是不可能查找到的所以
while(*p ! \0)//若要减少循环数则可以修改为
while ((p - str1) (int)strlen(str1) - (int)strlen(str2))三.strtok字符串分割
char* strtok (char* str, const char* sep);strtok函数能通过给定的一系列字符将一个字符串分割成许多子字符串的函数。它的第一个参数是需要被分割的字符串的首地址第二个参数是一个字符串的首地址该字符串是用作分隔符的字符集合。返回值是查找到的标记的首地址。
注意
sep参数指向一个字符串定义了用作分隔符的字符集合。第一个参数指定一个字符串它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。strtok函数找到str中的下一个标记并将其用 \0 结尾返回⼀个指向这个标记的指针。注 strtok函数会改变被操作的字符串所以被strtok函数切分的字符串⼀般都是临时拷贝的内容并且可修改strtok函数的第一个参数不为 NULL 函数将找到str中第一个标记strtok函数将保存它在字符串中的位置。strtok函数的第一个参数为 NULL 函数将在同一个字符串中被保存的位置开始查找下一个标记。如果字符串中不存在更多的标记则返回 NULL 指针。
例如
#includestdio.h
#includestring.h
int main()
{char email[] 3315898248qq.com;//待分割字符串char* sep .;//分隔符的字符集合char cp[20] { 0 };strcpy(cp, email);//将数据拷贝一份使用防止原数据被修改//char* ret strtok(email, sep);//第一次传参需传入待分割字符串首地址//while (ret ! NULL)//说明还未分割完//{// printf(%s\n, ret);// ret strtok(NULL, sep);//对同一个字符串进行分割第二次及以后的第一个参数为NULL//}//或者char* ret NULL;//利用for循环的特点先ret strtok(email, sep);判断ret ! NULL;//打印ret,再ret strtok(NULL, sep);判断ret ! NULL;循环到ret NULL结束for (ret strtok(email, sep); ret ! NULL; ret strtok(NULL, sep)){printf(%s\n, ret);}return 0;
}四.strerrorperror打印错误信息
char* strerror (int errnum);strerror函数可以把参数部分错误码转换为对应的错误信息将错误信息字符串的首地址返回来。
注意
在不同的系统和C语言标准库的实现中都规定了一些errno错误码一般是放在 errno.h 这个头文件中说明的。C语言程序启动的时候就会使用一个全局变量errno来记录程序的当前错误码只不过程序启动的时候errno是0表示没有错误当我们在使用标准库中的函数的时候发生了某种错误就会将对应的错误码存放在errno中。而一个错误码的数字是整数很难理解是什么意思所以每一个错误码都是有对应的错误信息的。strerror函数就可以将错误对应的错误信息字符串的地址返回。
#includeerrno.h
#includestring.h
#includestdio.h
//我们打印一下0~10这些错误码对应的信息
int main()
{int i 0;for (i 0; i 10; i){printf(%s\n, strerror(i));}return 0;
}例如打开一个文件fopen函数表示打开文件读或写当其执行成功时会返回文件的首地址执行失败时会返回一个空指针(NULL)。
int main()
{FILE* pf fopen(test.txt, r);//打开文件 ———— 读文件if (pf NULL)//若为NULL文件打开失败下一步查看错误信息{printf(%s\n, strerror(errno));//将错误码转换成对应的错误信息perror(fopen);//直接打印错误信息return 1;}return 0;
}printf(“%s\n”, strerror(errno)) 等价于 perror(“”)perror(“fopen”)可以代替strerror(errno)且效果更好加上fopen来明确错误来源于哪里。程序执行会加上一个冒号。
创作不易如果能帮到你的话能赏个三连吗感谢啦