当前位置:网站首页>【C语言进阶】----常见的字符串函数
【C语言进阶】----常见的字符串函数
2022-07-15 09:04:00 【whispar】
字符串函数
文章目录
一、strlen()
#include<stdio.h>
#include<string.h>
int main(){
char arr[] = "abcdef";//abcdef\0
int len = strlen(arr);
printf("%d",len);
return 0;
}

结果显示为字符串的长度
#include<string.h>
int main(){
char arr[] = {
'b','i','t'};
//[][][b][i][t][][][][][][][][]
int len = strlen(arr);//随机值
printf("%d\n",len);
return 0;
}

结果显示为随机值
size_t strlen ( const char * str );
字符串已经 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包含 ‘\0’ )。
参数指向的字符串必须要以 ‘\0’ 结束。
注意函数的返回值为size_t,是无符号的( 易错 )

#include <stdio.h>
int main()
{
const char*str1 = "abcdef";
const char*str2 = "bbb";
if(strlen(str2)-strlen(str1)>0)
{
printf("str2>str1\n");
}
else
{
printf("srt1>str2\n");
}
return 0;
}

结果显示,str1 >str2 ,与预期结果不符合,原因是strlen返回值是无符号的,相减之后作为无符号数处理,结果<0
正确方法:
if(strlen("abcdef")) > strlen("bbb")
模拟实现strlen()函数
计数器法
#include<assert.h>
size_t my_strlen(const char* str) {
size_t count = 0;
assert(str);
while (*str != '\0') {
count++;
str++;
}
return count;
}
int main() {
char arr[] = "abcdef";
size_t len = my_strlen(arr);
printf("%u", len);
return 0;
}
指针 —指针
#include<assert.h>
size_t my_strlen(const char* str) {
char* start = str;
while (*str != '\0') {
str++;
}
return (str - start);
}
递归实现
#include<assert.h>
size_t my_strlen(const char* str) {
assert(str);
if (*str != '\0') {
return 1 + my_strlen(str + 1);
}
return 0;
}
二、strcpy()
char* strcpy(char * destination, const char * source )
功能:复制字符串
将源指向的 C 字符串复制到目标所指向的数组中,包括终止空字符\0(并在该点停止)
#include <stdio.h>
#include<stdio.h>
int main() {
char str1[] = "Sample string";
char str2[40];
char str3[40];
strcpy(str2, str1);
strcpy(str3, "copy sucessful");
printf("str1 : %s\nstr2:%s\nstr3:%s\n", str1, str2, str3);
return 0;
}

模拟实现strcpy
#include<stdio.h>
#include<assert.h>
char* my_strcpy(char* arr, const char* str) {
assert(arr && str);
char* ret = arr;
while(*str != '\0') {
//*arr++ = *str++;
*arr = *str;
arr++;
str++;
}
*arr = *str;
return ret;
}
int main() {
char arr1[] = "abcdef";
char arr2[20] = {
0 };
my_strcpy(arr2, arr1);
printf("%s\n", arr2);
return 0;
}
对部分过程进行优化
char* my_strcpy(char* arr, const char* str) {
assert(arr && str);
char* ret = arr;
while (*arr++ = *str++);
return ret;
}

源字符串必须以 ‘\0’ 结束,会将源字符串中的 ‘\0’ 拷贝到目标空间,目标空间必须足够大且可变
int main(){
char name[20] ="XXXXXXXX";
strcpy(name,"zhang\0san");
printf("%s\n",name);
//char arr[] = {'b','i','t'};
//strcpy(name,arr);
return 0;
}


三、strcat()
char * strcat ( char * destination, const char * source );
功能实现:实现字符串的拼接
int main(){
char arr1[20] = "hello ";
strcat(arr1, "world");
printf("%s\n", arr1);
return 0;
}

源字符串必须以 ‘\0’ 结束,目标空间必须足够的大,能容纳下源字符串的内容。目标空间必须可修改。
模拟实现strcat()
#include<assert.h>
char* my_strcat(char* arr, const char* str) {
assert(arr && str);
char* ret = arr;
while (*arr != '\0') {
arr++;
}
while (*arr++ = *str++) {
;
}
return ret;
}
int main(){
char arr1[20] = "hello ";
my_strcat(arr1, "world!");
printf("%s\n", arr1);
return 0;
}

四、strcmp
int strcmp ( const char * str1, const char * str2 );
功能实现:
比较两个字符串(逐字符比较ASCLL码值)
#include<stdio.h>
#include<string.h>
int main() {
char arr1[] = "abcde";
char arr2[] = "abcdf";
int ret = strcmp(arr1, arr2);
if (ret > 0){
printf("arr1 > arr2");
}
else{
if (ret < 0)
printf("arr1 < arr2");
else
printf("arr1 = arr2");
}
return 0;
}

模拟实现strcmp()
#include<stdio.h>
#include<string.h>
#include<assert.h>
int my_strcmp(const char* str1, const char* str2) {
assert(str1 && str2);
while (*str1 == *str2) {
if (*str1 == '\0')
return 0;
str1++;
str2++;
}
//if (*str1 > *str2)
// return 1;
//else
// return -1;
//代码优化:
return (*str1 - *str2);
}

五、strncpy,strncmp,strncat
| 长度不受限制 | 长度受限制 |
|---|---|
| strcpy | strncpy |
| strcmp | strncmp |
| strcat | strncat |
strncpy
char * strncpy ( char * destination, const char * source, size_t num );
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main() {
char arr1[20] = "abcdef";
char arr2[] = "hello bit";
strncpy(arr1, arr2, 5);
printf("%s\n", arr1);
return 0;
}

对拷贝字符的长度进行了限制,仅拷贝5个字符,如果拷贝的字符不足五个,则补\0

strncat
char * strncat ( char * destination, const char * source, size_t num );
int main() {
char arr1[20] = "hello\0xxxxxx";
char arr2[] = "bit";
strncat(arr1,arr2,6);
return 0;
}
对追加字符串的长度进行了限制,并在追加后的字符串补‘\0’,如果限制长度超过了arr2,则不多补\0

strncmp
int strncmp ( const char * str1, const char * str2, size_t num );
int main() {
char arr1[] = "abcdef";
char arr2[] = "abc";
int ret = strncmp(arr1, arr2, 4);
if (ret == 0)
printf("==\n");
else if (ret < 0)
printf("<\n");
else
printf(">\n");
return 0;
}
对比较字符串的长度大小进行了限制,仅比较前num个字符

模拟实现strncmp
#include<assert.h>
int my_strncmp(const char* str1, const char* str2, size_t num) {
assert(str1 && str2);
int ret = 0;
while((num--) && !(ret = (unsigned char)*str1 - (unsigned char)*str2) && *str2)
{
str1++;
str2++;
}
return ret;
}
六、strstr()
char * strstr ( const char *str1, const char * str2);
功能演示:查找子字符串(KMP算法)
返回指向 str1 中第一次出现的 str2 的指针,如果 str2 不是 str1 的一部分,则返回空指针。
int main() {
char arr1[] = "abcdef";
char arr2[] = "de";
char* ret = strstr(arr1, arr2);
printf("%s\n", ret);
return 0;
}

模拟实现strstr()
char* my_strstr(const char* str1, const char* str2) {
const char* s1 = str1;
const char* s2 = str2;
char* p = str1;
while (*p) {
s1 = p;
s2 = str2;
while (*s1 != '\0'&&*s2 != '\0'&&*s1 == *s2) //判断字串
{
s1++;
s2++;
}
if (*s2 == '\0')
{
return p;
}
p++; //可能为情况二,修改s1位置再判断
}
return NULL;
}

七、strtok
char * strtok ( char * str, const char * sep );
功能演示
strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。
(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容
并且可修改,如果字符串中不存在更多的标记,则返回 NULL 指针)
#include <stdio.h>
#include <string.h>
int main()
{
char str[] = "- This, a sample.string.";
char* pch;
printf("切割 字符串 \"%s\" 为 片段:\n", str);
pch = strtok(str, " ,.-");
while (pch != NULL)
{
printf("%s\n", pch);
pch = strtok(NULL, " ,.-");
}
return 0;
}

八、strerror
char * strerror ( int errnum )
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main()
{
FILE* pFile;
pFile = fopen("unexist.ent", "r");
if (pFile == NULL)
printf("Error opening file unexist.ent: %s\n", strerror(errno));
return 0;
}

边栏推荐
- 打开有惊喜
- Week 4 Data analysis algorithms-Linear models for regression-Bias-Variance Analysis(Part B)
- Software test interface test interface authentication token authentication mock server interface encryption and decryption interface signature
- Technology companies have objected, and the UK cybersecurity act has been shelved
- How to realize the association between interfaces in JMeter?
- Switch and router technology: static route configuration and DHCP and VLAN configuration on the router
- C语言中的关键字struct、union、enum、typedef
- Proxmox ve 7.2 ISO image reset PVE root password
- 区别go array,slice,map
- 15.1.1 MySQL - date time function of MySQL, date format
猜你喜欢

Js13day (function definition method, call, apply, bind change this point, strict mode, closure, recursion, shallow copy method, deep copy function encapsulation)

How to realize the association between interfaces in JMeter?

VMware Photon OS 4 Install

Sword finger offer 06 Print linked list from end to end

Go语言指针

Session tracking technology cookies and sessions

Serein 【懒人神器】一款图形化、批量采集url、批量对采集的url进行各种nday检测的工具 摸鱼项目问题解决

Matlab微分方程的求解

Pytorch custom loss function, optimizer, and learning rate policy

易基因|染色质免疫共沉淀测序(ChIP-seq)分析实验全流程
随机推荐
面试官:如何定期去清理ES集群的数据
最常见算法面试题
Technology sharing | quick intercom -5g intercom
Introduction and Simulation of string function
如何把一个表格中的数据导入到对应数据库网站中
Kotlin click the blank position to hide the soft keyboard
Js13day (function definition method, call, apply, bind change this point, strict mode, closure, recursion, shallow copy method, deep copy function encapsulation)
Proxmox VE 7.2 ESXi OVA 导入
New development of Flink runtime for streaming batch integration
洽洽陈先保,六旬老汉复出,他还能折腾多少?
Practical application of Apache Flink in wing payment
Contact Chen Xianbao. How much can he deal with when the 60 year old man returns?
hyper子查询优雅实现join查询
Ardunio development interrupt mechanism
Application and practice of Apache Flink in betta
【有用的SQL】查Greenplum的数据字典
Session tracking technology cookies and sessions
基于ycbcr的图像火灾检测系统 基于matkab的GUI系统
.NET 全场景开发终于到来了
下次面试官再问高并发系统设计,直接把这篇文章甩给他
