字符串函数

article/2025/10/3 18:43:58

本文重点

重点介绍处理字符串+内存的库函数的使用和注意事项

  • 求字符串长度 ——strlen
  • 长度不受限制的字符串函数 ——strcpy、strcat、strcmp
  • 长度受限制的字符串函数介绍——strncpy、strncat、strncmp
  • 字符串查找——strstr、strtok
  • 错误信息报告——strerror
  • 字符操作

前言

C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在
常量字符串中或者字符数组 中。字符串常量适用于那些对它不做修改的字符串函数。

1、字符串函数介绍

1.1  strlen

size_t strlen( const char *string );

头文件是<string.h>

  • 字符串以‘\0’作为结束标志,strlen函数返回的是在字符串中‘\0’前面出现字符的个数(不包含‘\0’)。
  • 参数指向的字符串必须要以‘\0’结束。
  • 注意函数的返回值为size_t,是无符号的(易错)。

strlen函数的使用

 注:

如果是像这样初始化的那就有问题了,因为数组只开辟了'a'、'b'、‘c’、‘d’、‘e’这五个字符的空间,至于e后面是什么我们就不知道了但是strlen函数就是从前往后一直找'\0',直到找到了'\0'后停止,返回‘\0’之前的出现字符的个数。

那如果我们指定数组的长度又会怎么样呢?

看代码

这里输出的是一个正确的值,因为这里我们只初始化了5个字符的空间,剩下还有4个字符的空间没有初始化,这时候编译器会默认给它初始化0,0就是‘\0’的ASCII码值。 

 还有一个要注意的点是strlen返回的是无符号的值。看代码

就因为strlen返回的无符号的值,所以即使是负数也会返回一个很大的正数。那如果要这样用的话,可以将它强制类型转换为int类型就行了。

模拟实现strlen函数

方法1:

计数器方式

#include <stdio.h>
#include <assert.h>
int my_strlen(const char* str)
{assert(str!=NULL);//断言int count = 0;while (*str != '\0'){count++;str++;}return count;
}
int main()
{char arr[] = "asdfdg";int len=my_strlen(arr);printf("%d\n", len);return 0;
}

 方法2:

不创建临时变量计数器方式

int my_strlen(const char * str)
{
if(*str == '\0')
return 0;
else
return 1+my_strlen(str+1);
}

方法3:

指针-指针方式 

int my_strlen(char *s)
{
char *p = s;
while(*p != ‘\0’ )
p++;
return p-s;
}

1.2 strcpy

char *strcpy( char *strDestination, const char *strSource );  字符串拷贝 

头文件<string.h>

  •  Copies the C string pointed by source into the array pointed by destination, including the
    terminating null character (and stopping at that point)  意思是复制由字符指针源头指向的C语言字符串到另一个字符数组中,该字符数组字符指针目的地指向
  • 源头字符串必须以‘\0’结束
  • 会将源头字符串中的‘\0’拷贝到目标空间中
  • 目标空间必须足够大,确保能存放源头字符串
  • 目标空间必须可变

 strcpy使用

 

 如果你要这样初始化,那么程序就会挂掉,,strcpy也是读取到‘\0’才会停,这里的初始化就会造成越界访问,程序自然就挂了。如果你非要怎这样,你可以在d的后面再加上一个‘\0’或者限制数组的长度。

这里不难看出当字符串拷贝的时候会把‘\0’也拷贝进去。

注:这样也是错误的

 

arr2指向的是常量字符串,常量是不可修改的,而strcpy的目标空间必须是可修改的,所以这里的程序会崩掉 。

模拟实现strcpy

#include <stdio.h>
#include <assert.h>
//strcpy函数返回的是目标空间的起始地址
//strcpy函数返回类型的设置是为了实现链式访问
char* my_strcpy(char* dest, char* src)
{assert(dest && src);char* ret = dest;while (*dest++ = *src++){;}return ret;
}
int main()
{char arr1[20] = { 0 };char arr2[] = "hello";printf("%s\n", my_strcpy(arr1, arr2));return 0;
}

1.3 strcat

char *strcat( char *strDestination, const char *strSource );  追加字符串

头文件<string.h> 

  • Appends a copy of the source string to the destination string. The terminating null character
    in destination is overwritten by the first character of source, and a null-character is included
    at the end of the new string formed by the concatenation of both in destination.
    意思是将源字符串的副本追加到目标字符串。目标字符串中空字符被源字符串的第一个字符覆盖,并且在目标字符串中由这两个字符串联合成的新字符串的末尾包含一个空字符。
  • 源字符串必须以 '\0' 结束。
  • 目标空间必须有足够的大,能容纳下源字符串的内容。
  • 目标空间必须可修改。  

strcat的使用 

 

两个图对比一下,追加字符串的时候,源字符串中必须有‘\0’,并且目标字符串也必须要有‘\0’,从‘\0’的位置向后追加。

模拟实现strcat函数

#include <stdio.h>
#include <assert.h>
char* my_strcat(char* dest, char* src)
{assert(dest && src);char* ret = dest;//找目标空间中\0while (*dest){dest++;}//拷贝while (*dest++ = *src++){;}return ret;
}
int main()
{char arr1[20] = "hello";char arr2[] = "world";printf("%s\n", my_strcat(arr1, arr2));return 0;
}

这里有个问题这个模拟函数不能自己给自己追加,否则会死循环。 


1.4 strcmp

int strcmp( const char *string1, const char *string2 );   字符串比较

头文件<string.h> 

  • 此函数开始比较每个字符串的第一个字符。如果它们彼此相等,则继续使用以下对,直到字符不同或达到终止空字符。
  • 标准规定:
    第一个字符串大于第二个字符串,则返回大于0的数字
    第一个字符串等于第二个字符串,则返回0
    第一个字符串小于第二个字符串,则返回小于0的数字

strcmp使用

strcmp函数不是比较字符串的长度!!!

而是比较字符串对应位置上的字符的大小,如果相同,就比较下一对,直到不同或者都遇到\0

 模拟实现strcmp函数

#include <stdio.h>
#include <assert.h>
int my_strcmp(const char* s1, const char* s2)
{assert(s1 && s2);while (*s1 == *s2){if (*s1 == '\0' && *s2 == '\0'){return 0;//相等的情况}s1++;s2++;}//不相等的情况if (*s1 > *s2)return 1;elsereturn -1;
}
int main()
{char arr1[] = "asdfg";char arr2[] = "asd";int ret=my_strcmp(arr1, arr2);printf("%d\n", ret);return 0;
}

1.5 strncpy

char *strncpy( char *strDest, const char *strSource, size_t count );   

count是要拷贝字符的个数

头文件<string.h>

  •  拷贝num个字符从源字符串到目标空间。
  • 如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。

strncpy使用

 strncpy用起来相对安全,为神马说是相对安全呢,因为一个程序员想写bug你是拦不住他的。

如果是这种情况又会是怎样

它会不会真的把5字符拷贝过去

 

哦,没想到还真是,不够的用\0来补。


 1.6 strncat

char *strncat( char *strDest, const char *strSource, size_t count );

count是要追加的字符个数

头文件<string.h> 

strncat使用 

 注:这里追加的时候还会多追加一个'\0'。

可以自己给自己追加哦。


1.7 strncmp

int strncmp( const char *string1, const char *string2, size_t count );

count是要比较字符的个数

头文件<string.h> 

  • 比较到出现另个字符不一样或者一个字符串结束或者num个字符全部比较完。 

strncmp使用 


1.8 strstr

char *strstr( const char *str1, const char *str2 ); 

看str2是否是str1的子串

头文件<string.h>

  • Returns a pointer to the first occurrence of str2 in str1, or a null pointer if str2 is not part of
    str1     意思是返回一个指向str1中首次出现str2的指针,如果str2不是str1的一部分则返回一个空指针

strstr的使用

 模拟实现strstr函数

#include <stdio.h>
#include <string.h>
#include <assert.h>
char* my_strstr(const char* str1, const char* str2)
{assert(str1 && str2);const char* s1 = str1;const char* s2 = str2;const char* cur = str1;while (*cur){s1 = cur;s2 = str2;while (*s1 && *s2 && (*s1 == *s2)){s1++;s2++;}if (*s2 == '\0'){return (char*)cur;}cur++;}return NULL;//找不到的情况
}
int main()
{char arr1[] = "abcdefabcdef";char arr2[] = "cdef";char* ret = my_strstr(arr1, arr2);if (ret == NULL){printf("找不到子串\n");}else{printf("%s\n",ret);}return 0;
}

这里查找子串的话还可以用kmp算法,有兴趣可以去研究一下。 

1.9 strtok 

char * strtok ( char * str, const char * sep );
头文件<string.h>

  • sep参数是个字符串,定义了用作分隔符的字符集合
  • 第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记
  • strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:
    strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)
  • strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
  • strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
  • 如果字符串中不存在更多的标记,则返回 NULL 指针

    strtok使用
    #include <stdio.h>
    #include <string.h>
    int main()
    {char arr[] = "sadsf@zxc.fd";char buf[20] = { 0 };strcpy(buf, arr);const char* sep = "@.";char* str = NULL;for (str = strtok(buf, sep); str != NULL; str = strtok(NULL, sep)){printf("%s\n", str);}return 0;
    }
    
    #include <stdio.h>
    #include <string.h>
    int main()
    {char str[] = "- This, a sample string.";char* pch;printf("Splitting string \"%s\" into tokens:\n", str);pch = strtok(str, " ,.-");while (pch != NULL){printf("%s\n", pch);pch = strtok(NULL, " ,.-");}return 0;
    }
    1.10 strerror

char * strerror ( int errnum );
头文件<string.h>

  • 返回错误码,所对应的错误信息。 

strerror使用 

例子:

1.11 字符分类函数

函数如果他的参数符合下列条件就返回真(也就是非0的数)
iscntrl任何控制字符
isspace空白字符:空格‘ ’,换页‘\f’,换行'\n',回车‘\r’,制表符'\t'或者垂直制表符'\v'
isdigit十进制数字 0~9
isxdigit十六进制数字,包括所有十进制数字,小写字母a~f,大写字母A~F
islower小写字母a~z
isupper大写字母A~Z
isalpha字母a~z或A~Z
isalnum字母或者数字,a~z,A~Z,0~9
ispunct标点符号,任何不属于数字或者字母的图形字符(可打印)
isgraph任何图形字符
isprint任何可打印字符,包括图形字符和空白字符

1.12字符转换函数

int tolower ( int c );   大写转小写
int toupper ( int c );  小写转大写

example:

字母大小写转换

#include <stdio.h>
int main()
{char ch = 0;scanf("%c", &ch);if (ch >= 'A' && ch <= 'Z'){putchar(tolower(ch));}if (ch >= 'a' && ch <= 'z'){putchar(toupper(ch));}return 0;
}

本章完!


http://chatgpt.dhexx.cn/article/2RqnGJd8.shtml

相关文章

java 使用 jep3.5 解析公式自动计算(包含BigDecimal模式 浮点数精准计算)

下载地址: jep3.5 jar包与文档.rar 由于3.X并未上传maven所有只能下载jar包使用maven本地导入 <dependency><groupId>com.singularsys</groupId><artifactId>jep</artifactId><version>3.5</version><scope>system</scope…

【译】Jep 文档(1)——介绍(Introction)

原文连接&#xff08;http://www.singularsys.com/jep/doc/html/index.html&#xff09; 介绍 综述 Jep 是一个用于分析和计算数学表达式的java库。有了这个包&#xff0c;您就可以把数学公式当作是字符串&#xff0c;并且立即求出它们的值。许多常见的数学函数和常量都是内…

Java RMI反序列化/JEP290相关

RMI 远程过程调用 (Remote Procedure Call)是一种服务器-客户端模式&#xff0c; Java的RMI&#xff08;Remote Method Invocation&#xff09;是一种RPC实现。 其基本思想是程序员可以像本地那样&#xff0c;与远程对象进行交互。 步骤&#xff1a; 1、创建一个接口IRemote…

Java第三方库——Jep数学公式计算

Java第三方库——Jep数学公式计算 官网简介&#xff1a;JEP JAVA仅用几行代码解析和计算数学表达式。这个包允许用户以字符串的形式输入公式&#xff0c;并立即对其求值。JEP支持用户定义的变量、常量和函数。包括一些常用的数学函数和常量。 1.下载3.x版本依赖并引入 官方网站…

你知道Java中的JCP, JEP, JLS, JSR是什么意思吗?

目录 一、JCP 二、JSR 三、JLS 四、JEP 公众号&#xff1a;MCNU云原生&#xff0c;欢迎微信搜索关注&#xff0c;更多干货&#xff0c;及时掌握。 JCP, JEP, JLS, JSR这些概念是Java社区中的一些概念&#xff0c;但是没有没有经常关注社区的童鞋们未必知道这些缩写所代表的…

Java中JCP, JEP, JLS, JSR是什么

JCP Java Community Process JCP&#xff08;Java Community Process&#xff09;是一个开放的国际组织&#xff0c;主要由Java开发者以及被授权者组成&#xff0c;职能是发展和更新。 JCP维护的规范包括J2ME、J2SE、J2EE&#xff0c;XML&#xff0c;OSS&#xff0c;JAIN等。组…

java 使用JEP解析字符串计算公式 求值(附带自定义函数编写)

2.X 存在精确度问题 推荐使用3.X 参考文章: java 使用 jep3.5 解析公式自动计算(包含BigDecimal模式 浮点数精准计算) 1.增加jep依赖 <dependency><groupId>org.scijava</groupId><artifactId>jep</artifactId><version>2.4.2</versio…

使用Jep在Java中执行Python代码

接上次用Eclipse编写Python代码&#xff1a;使用Eclipse编写Python代码_Cc_Sonia的博客-CSDN博客_eclipse写python程序 为了把深度学习模型部署到Java App上&#xff0c;需要用Java调用Python。试过Jython&#xff0c;但它只对python2有效。。。最后supervisor建议使用Jep&…

jep的使用

参考jep官网:http://www.singularsys.com/jep/ Jep Java只用几行代码解析和评估数学表达式。此程序包允许您的用户输入公式作为字符串&#xff0c;并立即对其进行评估。Jep支持用户定义的变量&#xff0c;常量和函数。包括许多常见的数学函数和常数。 那么啰嗦,说白了就是支持…

python JEP安装

安装python ( 深坑 &#xff1a;安装之前请yum install python3-devel 避免出现i.e.: export LD_PRELOAD/usr/lib/libpython2.7.so.1.0 问题 ) 下载源码 Python Release Python 3.6.5 | Python.org 解压 进入目录 ./configure --prefix/opt/software/python --enab…

JEP:Java表达式分析器

JEP 是一个用于解析和计算数学表达式的 Java 类库。通过使用这个包你可以把公式看 作字符串并快速计算它们。其中内置了大量公共的数学函数和常量供用户使用。另外&#xff0c;你也 可以通过自定义变量、常量、函数等方式扩展 JEP 。 使用 JEP 计算一个字符串表达式包括…

java 使用JEP 进行节点计算

2.X 存在精确度问题 推荐使用3.X 参考文章: java 使用 jep3.5 解析公式自动计算(包含BigDecimal模式 浮点数精准计算)​​​​​​​ 1.JEP基础相关 请参考: java 使用JEP解析字符串计算公式 求值(附带自定义函数编写) 2.使用节点计算 注释写的很明白 要仔细看 public st…

如何在Java中执行Python模块?从认识JEP库开始

让我们从认识JEP库开始。 关注《Java学研大本营》 本教程基于带M1芯片的macOSX&#xff0c;用于Python 3.8/3.9和Java 11。 介绍 从我的实践来讲&#xff0c;我遇到的上一个挑战是&#xff0c;当基础应用引擎是Java的时候&#xff0c;我按常理应该添加一个新的机器学习功能。…

JEP 290 初识

JEP 290 初识 全局过滤器自定义过滤器内置过滤器 JEP 290是 oracle提供已一套JAVA反序列化机制&#xff0c;其并不是一种必须被强制执行的策略&#xff0c;而是需要程序员或者运维人员进行开发与启用。关于该机制的优缺点借用老外的一篇文章 https://dzone.com/articles/a-firs…

jep 使用方法与简介

1什么是jep JEP是Java expression parser的简称&#xff0c;即java表达式分析器&#xff0c;Jep是一个用来转换和计算数学表达式的java库。通过这个程序包&#xff0c;用户可以以字符串的形式输入一个、任意的公式&#xff0c;然后快速地计算出结果。Jep支持用户自定义变量、常…

那些人工智能明星公司都在搞什么?

事件&#xff1a;全球机器学习技术大会 时间&#xff1a;2021年1月13-14日 地点&#xff1a;金茂北京威斯汀大饭店 画外音&#xff1a;文末送所有PPT。 大会特邀近40位机器学习领域的技术领袖和行业应用专家&#xff0c;与1000来自电商、金融、汽车、智能制造、通信、工业互联网…

中国人工智能公司CIMCAI世界港航AI领军企业,自动化港口数字化码头,智能闸口各箱面箱况残缺检测视频流动态感知中国人工智能公司

中国人工智能公司CIMCAI世界港航AI领军企业&#xff0c;自动化港口数字化码头&#xff0c;智能闸口各箱面箱况残缺检测视频流动态感知&#xff0c;智能化港口码头数字化。CIMCAI已完成全球250万人工智能集装箱箱况检验&#xff0c;完成全球上亿集装箱信息&#xff0c;先进产品在…

外媒评选出来的中国五大人工智能(AI) 公司

https://www.toutiao.com/a6656628348795486727/ 2019-02-11 14:37:43 全球三分之二的人工智能投资正在进入中国市场&#xff0c;仅去年一年就帮助人工智能行业增长了67&#xff05;。 中国科技行业最近宣布了其前50家人工智能公司。其中包括14只“独角兽”--估值为10亿美元或…

【研究】那些人工智能公司现在发展到哪一步了?

作者&#xff1a;欧应刚 | 小编&#xff1a;小葱 近期&#xff0c;为了撰写《2018中国人工智能应用与生态研究报告》&#xff0c;中国软件网对我国人工智能产业应用和平台、生态建设进行了调研&#xff0c;以下是部分调研结果&#xff0c;更多内容见报告完整版。 1.已经有相当…

全球最强人工智能创新公司Top100榜单重磅发布!

自2012年至现在&#xff0c;名单上的100家跟人工智能相关的创业公司在367笔交易中累计融资总额达到117亿美元。以下是2017年的AI 100名单列表。 今天CB insights公布了第二个年度AI 100&#xff0c;即2018 AI 100 名单&#xff0c;如下图所示&#xff0c;这是其中100家最有希望…