当前位置: 首页 > news >正文

字符函数和字符串函数(1)

前言

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

1.求字符串长度
strlen

1.1 strlen

size_t strlen ( const char * str );

字符串已经 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包含 '\0' )。

参数指向的字符串必须要以 '\0' 结束。
注意函数的返回值为size_t,是无符号的( 易错 )
学会strlen函数的模拟实现

 

 strlen是一个库函数,是用来求字符串的长度的,len1和len2的值是一样的,因为str是char*类型的指针,指向的是a的地址。

#define _CRT_SECURE_NO_WARNINGS 1
#include <string.h>
#include<stdio.h>
int main()
{const char* str = "abcdef";size_t len1 = strlen("abcdef");size_t len2 = strlen(str);printf("%d\n", len1);printf("%d\n", len2);return 0;
}

 需要注意的是strlen遇到\0就会停止统计,假设我们在c的后面放上\0,那么答案就是3.


 我们需要注意的是strlen的返回值是size_t,是无符号数,所以-3被认定为无符号数,最高位的1被认为是正数,所以结果是>=0。

#define _CRT_SECURE_NO_WARNINGS 1
#include <string.h>
#include<stdio.h>
int main()
{//两个无符号数相减得到的还是无符号数//  3             - 6//-3//10000000000000000000000000000011//11111111111111111111111111111100//11111111111111111111111111111101//if (strlen("abc") - strlen("abcdef") > 0)printf(">=\n");elseprintf("<\n");return 0;
}


2.长度不受限制的字符串函数
strcpy
strcat
strcmp
 

 2.1 strcpy

char* strcpy(char * destination, const char * source );

源字符串必须以 '\0' 结束。
会将源字符串中的 '\0' 拷贝到目标空间。
目标空间必须足够大,以确保能存放源字符串。
目标空间必须可变。
学会模拟实现。

strcpy这个库函数的作用是 将指向的 C 字符串复制到目标指向的数组中,包括终止的 null 字符(并在该点停止)。

#define _CRT_SECURE_NO_WARNINGS 1
#include <string.h>
#include<stdio.h>
int main()
{char arr1[20] = {0};char arr2[] = "HELLO";strcpy(arr1, arr2);printf("%s\n", arr1);return 0;
}

 如果我们这样使用strcpy的话,就会出错,因为p里面存放的是常量字符串,是不能被修改的。

#define _CRT_SECURE_NO_WARNINGS 1
#include <string.h>
#include<stdio.h>
int main()
{char* p = "abcdefghi";char arr2[] = "HELLO";strcpy(p, arr2);//errprintf("%s\n", p);return 0;
}

2.2 strcat

char * strcat ( char * destination, const char * source );

源字符串必须以 '\0' 结束。
目标空间必须有足够的大,能容纳下源字符串的内容。
目标空间必须可修改。 

 strcat这个库函数的参数跟strcpy是一样的。这个库函数运行的第一步应该是找到目标字符串的末尾,也就是\0,找到之后再把源字符串的内容追加到目标字符串里面去,并且源字符串的\0也会追加过去。

#define _CRT_SECURE_NO_WARNINGS 1
#include <string.h>
#include<stdio.h>
int main()
{char arr1[20] = "abc";char arr2[] = "def";strcat(arr1, arr2);printf("%s\n", arr1);return 0;
}

 


2.3 strcmp

int strcmp ( const char * str1, const char * str2 );

 标准规定:
第一个字符串大于第二个字符串,则返回大于0的数字
第一个字符串等于第二个字符串,则返回0
第一个字符串小于第二个字符串,则返回小于0的数字

 strcmp比较的不是长度,而是对应位置上的字符的大小(ASCII码值)。

如果第一个字符大小相同则进行后面的比较。

 这里我们需要重要的是strcmp的返回值是int类型,两个参数都是char*的指针,是不能被改变的。

 strcmp规定是:

目标字符串>源字符串则返回>0;

目标字符串<源字符串则返回<0;

目标字符串=源字符串则返回=0;

 但是在vs编译器上分别是1,-1,0。在各个编译器上的返回值是不一样的,满足条件即可。

#define _CRT_SECURE_NO_WARNINGS 1
#include <string.h>
#include<stdio.h>
int main()
{char arr1[] = "abc";char arr2[] = "abq";int ret = strcmp(arr1, arr2);printf("%d", ret);return 0;
}

3.长度受限制的字符串函数介绍
strncpy
strncat
strncmp

3.1strncpy

char * strncpy ( char * destination, const char * source, size_t num );

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

 

 strncpy和strcpy的前两个参数是一样的,只是返回值是char*的指针,返回的是目标字符串。并且strncpy还多了一个参数size_t num,下面这个代码的意思就是将源字符串的前三个字符拷贝到目标字符数组里面去。

#define _CRT_SECURE_NO_WARNINGS 1
#include <string.h>
#include<stdio.h>
int main()
{char arr1[20] = { 0 };char arr2[] = "abcdefghi";strncpy(arr1, arr2, 3);printf("%s\n", arr1);return 0;
}

 


3.2 strncat

char * strncat ( char * destination, const char * source, size_t num );

 strncat和strcat的区别也是strncat要多一个参数size_t num,num就是我们要在目标字符串里面追加源字符串的字符个数,同时会将\0放在追加后的目标字符串的末尾。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main()
{char arr1[20] = "abc";char arr2[] = "defghi";strncat(arr1, arr2, 3);printf("%s\n", arr1);return 0;
}


3.2 strncmp

int strncmp ( const char * str1, const char * str2, size_t num );

 strncmp和strcmp的区别也是strncmp要多一个参数size_t num,num就是两个字符串要比较的字符个数。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main()
{char arr1[] = "abczef";char arr2[] = "abcqw";int ret = strncmp(arr1, arr2, 4);printf("%d\n", ret);return 0;
}

 因为'z'的ASCII码值大于’q‘,所以返回的是1.


4.strstr

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

 strstr就是在字符串中查找字符串,且是返回第一次出现的指针,如果没有则返回NULL。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{char arr1[] = "abcdefghiabcdeqghi";char arr2[] = "deq";char * ret = strstr(arr1, arr2);if (ret == NULL){printf("找不到\n");}else{printf("%s\n", ret);}return 0;
}

 

 如果次字符串出现多次,也是返回第一次出现的指针。


5.strtok

char * strtok ( char * str, const char * sep );

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

 strtok是用来切割字符串的,比如说下面这个代码,p里面是分隔符的集合,此时调用strtok函数就会在arr里面去找@,然后改成\0,同时返回z的地址。

#include<string.h>
int main()
{char arr[] = "sauxchnajd@yeah.net";char* p = "@.";char* s=strtok(arr, p);printf("%s\n", s);return 0;
}

 strtok函数会改变被操作的字符串,所以我们最好用一个临时拷贝的内容并且可修改,所以使用strcpy将字符串的内容拷贝过来,这个时候想怎么改buf都可以,对arr没有影响。

int main()
{char arr[] = "sauxchnajd@yeah.net";char* p = "@.";char buf[200] = {0};strcpy(buf, arr);char* s=strtok(buf, p);printf("%s\n", s);return 0;
}

strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。所以我们如果要找第二个分隔符,我们就进行第二次调用strtok,第一个参数用NULL,这时strtok就会在第一个标记开始往后查找。

int main()
{char arr[] = "sauxchnajd@yeah.net";char* p = "@.";char buf[200] = {0};strcpy(buf, arr);char* s=strtok(buf, p);printf("%s\n", s);s = strtok(NULL, p);printf("%s\n", s);return 0;
}

 我们再次调用效果和第二次就是一样的了,在标记后往后查找。

int main()
{char arr[] = "sauxchnajd@yeah.net";char* p = "@.";char buf[200] = {0};strcpy(buf, arr);char* s=strtok(buf, p);printf("%s\n", s);s = strtok(NULL, p);printf("%s\n", s);s = strtok(NULL, p);printf("%s\n", s);return 0;
}

如果字符串中不存在更多标记的时候,则返回空指针。 

strtok函数的真正用法是下面这个代码:

当使用p第一次切割arr的时候,如果返回值不是NULL,则打印出s指向的字符串,然后调整阶段就二次调用,使用NULL。这个for循环的初始化部分只执行了一次,因为strtok这个函数只有第一次传的是非空指针,后面都是NULL。

int main()
{char arr[] = "sauxchnajd@yeah.net";char* p = "@.";char buf[200] = {0};strcpy(buf, arr);char* s = NULL;for (s = strtok(buf, p);s!=NULL;s=strtok(NULL,p)){printf("%s\n", s);}return 0;
}

 


6.strerror

char * strerror ( int errnum );

strerror这个函数是将错误码翻译成错误信息,返回错误信息的字符串的起始地址 。

那么什么是错误码呢?无论是使用库函数还是进行正规的软件设计的时候都会设计错误码,就是当程序发生错误的时候,会报出错误信息。在C语言中,如果发生错误就会将错误码放在errno的变量中,errno是一个全局变量,可以直接使用。我们如果想知道0,1,2,3这种数字在错误码中代表着上面,那我们就使用strerror来试一下:

int main()
{int i = 0;for (i = 0; i < 10; i++){printf("%d: %s\n", i, strerror(i));}return 0;
}

 但正常的使用方法是发生什么问题我们就将这个问题的错误码传给strerror,然后翻译出来。

这里举一个打开文件的例子,fopen 以读的形式打开文件,如果文件存在,打开成功,如果文件不存在,打开失败。

int main()
{FILE* pf = fopen("add.txt", "r");if (pf == NULL){printf("打开文件失败,原因是:%s\n", strerror(errno));return 1;}else{printf("打开文件成功\n");}return 0;
}

 

 这里还有一个函数叫perror,直接打印错误码,所对应的错误信息。可以这样理解,perror == printf + strerror。

int main()
{FILE* pf = fopen("add.txt", "r");if (pf == NULL){perror("打开文件失败"); return 1;}else{printf("打开文件成功\n");}return 0;
}


今天的分享到这里就结束啦!谢谢老铁们的阅读,让我们下期再见。

相关文章:

字符函数和字符串函数(1)

前言 C语言中对字符和字符串的处理很是频繁&#xff0c;但是C语言本身是没有字符串类型的&#xff0c;字符串通常放在 常量字符串 中或者 字符数组 中。 字符串常量 适用于那些对它不做修改的字符串函数. 1.求字符串长度 strlen 1.1 strlen size_t strlen ( const char * s…...

Visual Studio Code从GIT拉取vue项目并运行

安装Visual Studio Code 安装GIT 安装node.js&#xff0c;配置好环境变量 拉取项目 文章一 文章二 运行项目 文章一 提交代码 文章一...

【知识分享】Java获取全年每个月的有几周且每周是几号到几号

加哥本周给大家分享一期怎么用java把全年每个月有几周&#xff0c;本周是几号到几号的工具类。便于大家根据需求获取想要的形式进行改造。话不多说&#xff0c;直接给大家上代码。 package com.techfantasy.common.utils; import com.techfantasy.common.entity.DateRange; i…...

学信息系统项目管理师第4版系列11_信息安全管理

1. 信息安全基础 1.1. 保密性(Confidentiality&#xff09; 1.1.1. 信息不被未授权者知晓的属性 1.1.2. 确保信息不暴露给未授权的实体或进程 1.2. 完整性(Integrity) 1.2.1. 信息是正确的、真实的、未被篡改的、完整无缺的属性 1.2.2. 只有得到允许的人才能修改数据&…...

sql注入原理分析

...

Mac磁盘空间满了怎么办?Mac如何清理磁盘空间

你是不是发现你的Mac电脑存储越来越满&#xff0c;甚至操作系统本身就占了100多G的空间&#xff1f;这不仅影响了电脑的性能&#xff0c;而且也让你无法存储更多的重要文件和软件。别担心&#xff0c;今天这篇文章将告诉你如何清除多余的文件&#xff0c;让你的Mac重获新生。 一…...

能ping通但无法上网的问题

大家好&#xff0c;今天我要和大家分享一下当你的IP地址能够成功 ping 通&#xff0c;却无法上网时该如何解决这个问题。这是一个相当常见的情况&#xff0c;在网络故障排查中经常遇到。别担心&#xff0c;我将为你揭开这个谜题&#xff0c;提供一些解决方案和技巧。 首先&…...

仿制 Google Chrome 的恐龙小游戏

通过仿制 Google Chrome 的恐龙小游戏&#xff0c;我们可以掌握如下知识点&#xff1a; 灵活使用视口单位掌握绝对定位JavaScript 来操作 CSS 变量requestAnimationFrame 函数的使用无缝动画实现 页面结构 实现页面结构 通过上述的页面结构我们可以知道&#xff0c;此游戏中…...

Redis面试题(五)

文章目录 前言一、使用过 Redis 做异步队列么&#xff0c;你是怎么用的&#xff1f;有什么缺点&#xff1f;二、 什么是缓存穿透&#xff1f;如何避免&#xff1f;什么是缓存雪崩&#xff1f;何如避免&#xff1f;总结 前言 使用过 Redis 做异步队列么&#xff0c;你是怎么用的…...

组队竞赛(int溢出问题)

目录 一、题目 二、代码 &#xff08;一&#xff09;没有注意int溢出 &#xff08;二&#xff09;正确代码 1. long long sum0 2. #define int long long 3. 使用现成的sort函数 一、题目 二、代码 &#xff08;一&#xff09;没有注意int溢出 #include <iostream&g…...

Swift SwiftUI 隐藏键盘

如果仅支持 iOS 15 及更高版本&#xff0c;则可以通过聚焦和取消聚焦来激活和关闭文本字段的键盘。 在最简单的形式中&#xff0c;这是使用 FocusState 属性包装器和 focusable() 修饰符完成的-第一个存储一个布尔值&#xff0c;用于跟踪第二个当前是否被聚焦。 Code struct C…...

Python与数据分析--Pandas-1

目录 1.Pandas简介 2.Series的创建 1.通过数组列表来创建 2.通过传入标量创建 3.通过字典类型来创建 4.通过numpy来创建 3.Series的索引和应用 1. 通过index和values信息 2. 通过切片方法获取信息 4.DataFrame的创建 1.直接创建 2.矩阵方式创建 3.字典类型创建 5.…...

如何完美通过token获取用户信息(springboot)

1. 什么是Token&#xff1f; 身份验证令牌&#xff08;Authentication Token&#xff09;&#xff1a;在身份验证过程中&#xff0c;“token” 可以表示一个包含用户身份信息的令牌。 例如 Token&#xff08;JWT&#xff09;是一种常见的身份验证令牌&#xff0c;它包含用户的…...

2023 “华为杯” 中国研究生数学建模竞赛(B题)深度剖析|数学建模完整代码+建模过程全解全析

华为杯数学建模B题 当大家面临着复杂的数学建模问题时&#xff0c;你是否曾经感到茫然无措&#xff1f;作为2021年美国大学生数学建模比赛的O奖得主&#xff0c;我为大家提供了一套优秀的解题思路&#xff0c;让你轻松应对各种难题。 让我们来看看研赛的B题呀~&#xff01; 问…...

文件相关工具类

文章目录 1.MultipartFile文件转File2.读取文件(txt、json)3.下载网络文件4.压缩文件 1.MultipartFile文件转File public File transferToFile(MultipartFile multipartFile) { // 选择用缓冲区来实现这个转换即使用java 创建的临时文件 使用 MultipartFile.transferto()…...

18795-2012 茶叶标准样品制备技术条件

声明 本文是学习GB-T 18795-2012 茶叶标准样品制备技术条件. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本标准规定了各类茶叶(除再加工茶)标准样品的制备、包装、标签、标识、证书和有效期。 本标准适用于各类茶叶(除再加工茶)感官品质…...

C++11互斥锁的使用

是C11标准库中用于多线程同步的库&#xff0c;提供互斥锁(mutex)及其相关函数。 以下是一些基本的使用示例&#xff1a; 1.创建和销毁互斥锁 #include <mutex>std::mutex mtx;2.加锁 std::lock_guard<std::mutex> lock(mtx); // 加锁 // 或者 mtx.lock(); //…...

unity 桌面程序

using System; using System.Collections; using System.Collections.Generic; using System.Runtime.InteropServices; using UnityEngine; public class chuantou : MonoBehaviour { [DllImport(“user32.dll”)] public static extern int MessageBox(IntPtr hwnd,string t…...

echarts统一纵坐标y轴的刻度线,刻度线对齐。

要求&#xff1a; 纵坐标刻度线对齐&#xff1b;刻度间隔为5&#xff1b;去掉千位默认的逗号&#xff1b;刻度最小是0. 效果图&#xff1a; 代码&#xff1a; yAxis: [{type: "value",position: "left",name: "kW",offset: 100,nameTextStyle:…...

一个数据库版本兼容问题

mysql旧的版本号是&#xff1a;5.3.10 本机版本号是&#xff1a;8.0.22 报错&#xff1a;“com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Could not create” 1.程序里做兼容&#xff1a; <dependency><groupId>mysql</groupId>…...

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...

服务器硬防的应用场景都有哪些?

服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式&#xff0c;避免服务器受到各种恶意攻击和网络威胁&#xff0c;那么&#xff0c;服务器硬防通常都会应用在哪些场景当中呢&#xff1f; 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互

引擎版本&#xff1a; 3.8.1 语言&#xff1a; JavaScript/TypeScript、C、Java 环境&#xff1a;Window 参考&#xff1a;Java原生反射机制 您好&#xff0c;我是鹤九日&#xff01; 回顾 在上篇文章中&#xff1a;CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错

出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上&#xff0c;所以报错&#xff0c;到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本&#xff0c;cu、torch、cp 的版本一定要对…...

Ascend NPU上适配Step-Audio模型

1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统&#xff0c;支持多语言对话&#xff08;如 中文&#xff0c;英文&#xff0c;日语&#xff09;&#xff0c;语音情感&#xff08;如 开心&#xff0c;悲伤&#xff09;&#x…...

关于 WASM:1. WASM 基础原理

一、WASM 简介 1.1 WebAssembly 是什么&#xff1f; WebAssembly&#xff08;WASM&#xff09; 是一种能在现代浏览器中高效运行的二进制指令格式&#xff0c;它不是传统的编程语言&#xff0c;而是一种 低级字节码格式&#xff0c;可由高级语言&#xff08;如 C、C、Rust&am…...

html-<abbr> 缩写或首字母缩略词

定义与作用 <abbr> 标签用于表示缩写或首字母缩略词&#xff0c;它可以帮助用户更好地理解缩写的含义&#xff0c;尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时&#xff0c;会显示一个提示框。 示例&#x…...

Linux部署私有文件管理系统MinIO

最近需要用到一个文件管理服务&#xff0c;但是又不想花钱&#xff0c;所以就想着自己搭建一个&#xff0c;刚好我们用的一个开源框架已经集成了MinIO&#xff0c;所以就选了这个 我这边对文件服务性能要求不是太高&#xff0c;单机版就可以 安装非常简单&#xff0c;几个命令就…...

第八部分:阶段项目 6:构建 React 前端应用

现在&#xff0c;是时候将你学到的 React 基础知识付诸实践&#xff0c;构建一个简单的前端应用来模拟与后端 API 的交互了。在这个阶段&#xff0c;你可以先使用模拟数据&#xff0c;或者如果你的后端 API&#xff08;阶段项目 5&#xff09;已经搭建好&#xff0c;可以直接连…...

uni-app学习笔记三十五--扩展组件的安装和使用

由于内置组件不能满足日常开发需要&#xff0c;uniapp官方也提供了众多的扩展组件供我们使用。由于不是内置组件&#xff0c;需要安装才能使用。 一、安装扩展插件 安装方法&#xff1a; 1.访问uniapp官方文档组件部分&#xff1a;组件使用的入门教程 | uni-app官网 点击左侧…...