C語言(字符函數和字符串函數)1

?????? ????????????????Hi~!這里是奮斗的小羊,很榮幸各位能閱讀我的文章,誠請評論指點,關注+收藏,歡迎歡迎~~? ? ?

????????????????????????💥個人主頁:小羊在奮斗

????????????????????????💥所屬專欄:C語言? ?

????????本系列文章為個人學習筆記,在這里撰寫成文一為鞏固知識,二為同樣是初學者的學友展示一些我的學習過程及心得。文筆、排版拙劣,望見諒。?

????????????????????????????????1、字符分類函數

????????????????????????????????2、字符轉換函數

????????????????????????????????3、strlen 的使用和模擬實現

????????????????????????????????4、strcpy?的使用和模擬實現

????????????????????????????????5、strcat?的使用和模擬實現

1、字符分類函數

? ? ? ? C語言中有一些專門作字符分類的函數,使用這些函數需要包含頭文件 ctype.h

isalnum

檢查一個字符是否是字母或數字
(函數)

isalpha

檢查一個字符是否是字母
(函數)

islower

檢查一個字符是否是小寫字母
(函數)

isupper

檢查一個字符是否是大寫字母
(函數)

isdigit

檢查字符是否為數字
(函數)

isxdigit

檢查一個字符是否是十六進制的字符
(函數)

iscntrl

檢查一個字符是否是控制字符
(函數)

isgraph

檢查一個字符是否是圖形字符
(函數)

isspace

檢查一個字符是否是空白字符
(函數)

isblank

(C99)

檢查一個字符是否是空格字符
(函數)

isprint

檢查一個字符是否是可打印字符
(函數)

ispunct

檢查一個字符是否是標點字符

? ? ? ? 更多詳細內容請點擊跳轉閱讀 —>?C 標準庫頭文件 - cppreference.com?


? ? ? ? 這些函數的使用方法、返回值等基本是一致的,這里就以 islower 函數為例,寫一個將字符串中非大寫的字母轉化為大寫字母的示例。

?

?2、字符轉換函數

? ? ? ? C語言中有兩個實現大小寫轉換的函數,tolower將大寫字母轉小寫)?和 toupper將小寫字母轉大寫)。

????????那既然有了這兩個函數,上面將字符串中的小寫字母轉換為大寫字母的代碼就可以簡化一下了。

?

3、strlen 的使用和模擬實現

? ? ? ? 3.1 strlen 的返回值

? ? ? ? strlen 函數我們已經非常的熟悉,之前也介紹了兩種模擬 strlen 函數的方法,這里再關于strlen 的使用做一些補充,同時再介紹另一種 strlen 的模擬實現方法。

????????

? ? ? ? 以前我們在使用 strlen 函數的時候,可能沒有細心地關注過 strlen 的返回值類型,有時候我們使用 int 類型來接收它的返回值好像也沒出現什么問題,但其實這是一個很值得我們去注意的一個問題。來看下面的示例:

? ? ? ? 按道理來說-3小于0應該打印的是“<=”,但結果卻并不是。其中的原因就在于 strlen 的返回值類型是 size_t 類型,兩個 size_t 類型的值相減還是 size_t 類型,而我們知道整型是以補碼的形式存儲的,所以 size_t 類型會把-3的補碼當做一個很大的正整數,這個數當然是大于0的,所以結果是打印出了 “>”。而如果我們想讓它輸出我們想要的結果,只需要強制類型轉換就行。

? ? ? ? 3.2 strlen 的模擬實現?

?????????之前的文章中我們用了指針遍歷數組和指針-指針兩種方法來模擬 strlen 函數,這里我們再使用另一種方法來模擬實現——遞歸。

#include <stdio.h>
#include <assert.h>size_t my_strlen(char* str)
{assert(str != NULL);if (*str != '\0'){return 1 + my_strlen(++str);}else{return 0;}
}int main()
{char str[] = "Are you ok?";size_t len = my_strlen(str);printf("%zd\n", len);return 0;
}

? ? ? ? 我們之前說過,遞歸就是一個把大事化小的過程,適合于解決一些簡單重復的操作,就像上面重復讀取一個字符并判斷的過程。這個方法很簡單,一眼就能明白其中的原理,我就不過多闡述了。值得一說的是,這個方法并沒有創建新變量,這是區別于前兩種方法的地方。?

4、strcpy 的使用和模擬實現

? ? ? ? 4.1 strcpy 的用法?

? ? ? ? strcpy 是一個字符串拷貝函數,它的作用是把第二個參數所指的字符串拷貝給第一個參數所指的字符串數組中,注意不要搞反了。

????????更多詳細介紹請點擊查閱 —>?strcpy, strcpy_s - cppreference.com

?????????

? ? ? ? 使用 strcpy 也需要包含頭文件 <string.h>,是比較簡單的,但是有幾個需要特別注意的點。?

(1)源字符串必須以 ‘\0’ 結束;

? ? ? ? 就像 strlen 函數一樣,strcpy 函數也需要知道它應該在哪里停止拷貝。?

(2)會將源字符串中的 ‘\0’ 拷貝到目標空間;

? ? ? ? ?在上面的代碼中我們使用 strlen 函數證明了這點。

(3)目標空間必須足夠大,以確保能放得下字符串;

? ? ? ? 以上面的代碼為例,如果我們定義的字符數組 str2 太小,程序就會出錯。

??

(4)目標空間必須可修改。

? ? ? ? ?這里舉個反例來證明這一點。

? ? ? ? 將常量字符串 “abc” 存到字符指針變量 ps 中,前面說過常量字符串是不能被修改的,所以程序就出錯了。?

? ? ? ? 4.2 strcpy 的模擬實現?

? ? ? ? 就像 strlen 函數一樣,我們同樣也可以模擬實現一個 strcpy 函數,完成字符串拷貝的功能。?

#include <stdio.h>
#include <assert.h>
#include <string.h>void my_strcpy(char* dest, const char* sour)
{assert(dest != NULL);assert(sour != NULL);while (*sour != '\0'){*dest = *sour;sour++;dest++;}*dest = *sour;//\0
}int main()
{char str1[] = "what can I say? man.";char str2[50] = { 0 };my_strcpy(str2, str1);printf("%s\n", str2);printf("%zd\n", strlen(str2));return 0;
}

? ? ? ? 邏輯也是特別簡單的,只不過我們要特別注意字符 ‘\0’ 也需要拷貝過去。

? ? ? ? 4.3 strcpy 的返回值?

? ? ? ? 關于 strcpy 函數我們可能會忽略了它的返回值,因為我們會覺得這個函數并不需要什么返回值,但其實它是有返回值的,既然有返回值,那它的返回值就有用,所以嚴格來說我們上面模擬實現的 strcpy 函數返回值應該為 char * 而不是 void 。strcpy 函數返回的是目標字符串的首地址,這使得 strcpy 可以鏈式操作。

? ? ? ??所以上面的代碼可以更新為:

#include <stdio.h>
#include <assert.h>
#include <string.h>char* my_strcpy(char* dest, const char* sour)
{assert(dest != NULL);assert(sour != NULL);char* pd = dest;while (*sour != '\0'){*dest = *sour;sour++;dest++;}*dest = *sour;//\0return pd;
}int main()
{char str1[] = "what can I say? man.";char str2[50] = { 0 };char* ps = my_strcpy(str2, str1);printf("%s\n", ps);printf("%s\n", my_strcpy(str2, str1));printf("%zd\n", strlen(str2));return 0;
}

? ? ? ? 4.4 strcpy 模擬實現的優化?

? ? ? ? 雖然我們已經完成了 strcpy 函數的模擬實現,但上面的代碼還可以優化。因為字符‘\0’的特殊,上面的代碼中我們是將普通字符和‘\0’字符分開處理的,那是否可以有個辦法將這兩步合在一起呢?

? ? ? ? 來體會下面這條代碼:

? ? ? ? 我們用一條代碼就實現了拷貝字符串,包括拷貝字符‘\0’。其中的原理也是非常簡單,當字符‘\0’拷貝到目的空間后,括號中表達式的值為0,就自動跳出了循環。需要說明的是兩個指針變量都是先解引用,然后再自增的。

5、strcat 的使用和模擬實現

?????????5.1 strcat 的用法

? ? ? ? strcat 函數的作用是將源字符串拼接到目標字符串的后面,跟 strcpy 函數類似,strcat 是將第二個參數所指的字符串拼接到第一個參數所指的字符串后面。

? ? ? ? 更多詳細的介紹請點擊閱讀 —>?strcat, strcat_s - cppreference.com

? ? ? ? 同樣的,strcat 函數也有幾個需要注意的點:?

? ? ? ? (1)源字符串必須以‘\0’結束;

? ? ? ? (2)目標字符串中也得有‘\0’,否則沒法知道拼接在哪里;

? ? ? ? (3)目標空間必須足夠大;

? ? ? ? (4)目標空間必須可修改。

? ? ? ? 5.2 strcat 的返回值

? ? ? ? 類比 strcpy,strcat 也是有返回值的,并且返回值也是目標字符串的首地址。

? ? ? ? 5.3 strcat 的模擬實現

? ? ? ? 我們依然可以自己寫一個函數來模擬實現 strcat 的功能,方法很簡單,類似于模擬實現 strcpy 的方法,我們只需要想辦法將源字符串拼接到目標字符串末尾就行,相信對于現在有點基礎的我們來說這并不是什么難事。

#include <stdio.h>
#include <assert.h>char* my_strcat(char* dest, const char* sour)
{assert(dest != NULL);assert(sour != NULL);char* pd = dest;while (*dest++);dest--;//覆蓋掉目標字符串中的\0while (*dest++ = *sour++);return pd;
}int main()
{char str1[20] = "hello ";char str2[] = "world";char *ps = my_strcat(str1, str2);printf("%s\n", ps);return 0;
}

? ? ? ? 上面我們是將一個字符串與另一個字符串拼接在一起,那能不能將一個字符串拼接到自己的末尾呢?

? ? ? ? 可以看到,用我們自己寫的函數不能實現字符串自己拼接到自己后面,這是因為拼接的過程是在目標字符串末尾的 ‘\0’ 處開始拼接的,也就是說目標字符串的第一個字符會覆蓋掉它自己末尾的 ‘\0’,那函數的第二個參數指針就永遠也找不到 ‘\0’ 以結束拼接,就會陷入死循環。

????????但是 strcat 函數可以,不過?strcat 函數并不能保證這件事情,也就是說上面能成功是偶然的。?

? ? ? ? ? ?如果覺得我的文章還不錯,請點贊、收藏 + 關注支持一下,我會持續更新更好的文章。?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/19491.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/19491.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/19491.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

python API自動化(接口測試基礎與原理)

1.接口測試概念及應用 什么是接口 接口是前后端溝通的橋梁&#xff0c;是數據傳輸的通道&#xff0c;包括外部接口、內部接口,內部接口又包括&#xff1a;上層服務與下層服務接口&#xff0c;同級接口 外部接口&#xff1a;比如你要從 別的網站 或 服務器 上獲取 資源或信息 &a…

SpringMVC框架學習筆記(四):模型數據 以及 視圖和視圖解析器

1 模型數據處理-數據放入 request 說明&#xff1a;開發中, 控制器/處理器中獲取的數據如何放入 request 域&#xff0c;然后在前端(VUE/JSP/...)取出顯 示 1.1 方式 1: 通過 HttpServletRequest 放入 request 域 &#xff08;1&#xff09;前端發送請求 <h1>添加主人…

使用dockerfile快速構建一個帶ssh的docker鏡像

不多說先給代碼 FROM ubuntu:22.04 # 基礎鏡像 可替換為其他鏡像 USER root RUN echo root:root |chpasswd RUN apt-get update -y \&& apt-get install -y git wget curl RUN apt-get install -y openssh-server vim && apt clean \&& rm -rf /tmp/…

在SpringBoot項目中實現切面執行鏈功能

1.定義切面執行鏈頂級接口 AspectHandler /*** 切面執行鏈**/ public interface AspectHandler {/*** 設置排除項* param excludes*/default void setExcludes(List<String> excludes) {}/*** 獲取排除項* return*/default List<String> getExcludes() {return ne…

事務與并發控制

事務&#xff08;Transaction0&#xff09;&#xff1a;要么全做&#xff0c;要么全不做&#xff1b; 事務ACID&#xff1a;原子性Atomicity&#xff1b;一致性Consistency&#xff1b;隔離性Isolation&#xff1b;持久性Durability&#xff1b; 并發操作問題&#xff1a; 1.…

基于RNN和Transformer的詞級語言建模 代碼分析 _generate_square_subsequent_mask

基于RNN和Transformer的詞級語言建模 代碼分析 _generate_square_subsequent_mask flyfish Word-level Language Modeling using RNN and Transformer word_language_model PyTorch 提供的 word_language_model 示例展示了如何使用循環神經網絡RNN(GRU或LSTM)和 Transforme…

汽車IVI中控開發入門及進階(二十二):video decoder視頻解碼芯片

前言: 視頻解碼器在許多汽車、專業和消費視頻應用中仍有需求。Analog Devices是模擬視頻產品領域的行業領導者,提供一系列視頻解碼器,可將標準(SD,standard definition)和高清(HD,High definition)分辨率的模擬視頻高質量轉換為MIPI或TTL格式的數字視頻數據。典型的應…

【AI大模型】如何讓大模型變得更聰明?基于時代背景的思考

【AI大模型】如何讓大模型變得更聰明 前言 在以前&#xff0c;AI和大模型實際上界限較為清晰。但是隨著人工智能技術的不斷發展&#xff0c;基于大規模預訓練模型的應用在基于AI人工智能的技術支持和幫助上&#xff0c;多個領域展現出了前所未有的能力。無論是自然語言處理、…

算法刷題筆記 差分矩陣(C++實現)

文章目錄 題目前言題目描述解題思路和代碼實現 題目前言 這道題是一道差分算法的拓展題型&#xff0c;是算法刷題筆記到目前為止我認為最困難的題目之一。因此&#xff0c;這篇題解博客的過程記錄也最為詳細&#xff0c;希望能夠為你帶來幫助。 題目描述 輸入一個n行m列的整…

JavaScript的垃圾回收機制

No.內容鏈接1Openlayers 【入門教程】 - 【源代碼示例300】 2Leaflet 【入門教程】 - 【源代碼圖文示例 150】 3Cesium 【入門教程】 - 【源代碼圖文示例200】 4MapboxGL【入門教程】 - 【源代碼圖文示例150】 5前端就業寶典 【面試題詳細答案 1000】 文章目錄 一、垃圾…

匹配字符串

自學python如何成為大佬(目錄):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 Python提供了re模塊&#xff0c;用于實現正則表達式的操作。在實現時&#xff0c;可以使用re模塊提供的方法&#xff08;如search()、match()、finda…

深入理解Redis:多種操作方式詳解

Redis&#xff08;Remote Dictionary Server&#xff09;是一款高性能的開源鍵值存儲系統&#xff0c;廣泛應用于緩存、會話管理、實時分析等領域。它支持多種數據結構&#xff0c;如字符串、哈希、列表、集合和有序集合等&#xff0c;提供了豐富的操作命令。本篇博客將詳細介紹…

信息系統項目管理師0603:項目整合管理 — 考點總結(可直接理解記憶)

點擊查看專欄目錄 文章目錄 項目整合管理 — 考點總結(可直接理解記憶) 輸入、輸出、工具和技術 歷年考題直接考輸入,輸出、工具和技術的有17年11月第34、35,19年5月第34、35,20年11月27、28,21年5月第26,28,21年11月第28,22年5月第25,22年11月第22考題 項目章程是正…

CasaOS玩客云安裝全平臺高速下載器Gopeed并實現遠程訪問

&#x1f49d;&#x1f49d;&#x1f49d;歡迎來到我的博客&#xff0c;很高興能夠在這里和您見面&#xff01;希望您在這里可以感受到一份輕松愉快的氛圍&#xff0c;不僅可以獲得有趣的內容和知識&#xff0c;也可以暢所欲言、分享您的想法和見解。 推薦:kwan 的首頁,持續學…

BufferQueue 的工作原理

bufferQueue 是 Android 圖形棧中的一個核心組件,它在生產者和消費者之間傳遞緩沖區(buffer)。它通常用于圖形緩沖區管理,特別是在 SurfaceFlinger 和其他圖形相關的組件中。理解 BufferQueue 的工作原理對開發高性能圖形應用和解決圖形渲染問題非常有幫助。 BufferQueue …

基于Python的酒店客房入侵檢測系統的設計與實現

基于Python的酒店客房入侵檢測系統的設計與實現 開發語言:Python 數據庫&#xff1a;MySQL所用到的知識&#xff1a;Django框架工具&#xff1a;pycharm、Navicat、Maven 系統功能實現 酒店客房入侵管理界面 結合上文的結構搭建和用戶需求&#xff0c;酒店客房入侵檢測系統的…

【Unity Shader入門精要 第12章】屏幕后處理效果(一)

1. 原理和過程 屏幕后處理是綁定攝像機的&#xff0c;通過抓取當前攝像機渲染的圖像作為 SrcTextrue&#xff0c;然后按需依次調用處理接口&#xff0c;對 SrcTexture 進行處理&#xff0c;最后將處理完成的 DstTexture 顯示到屏幕上&#xff0c;整個過程的調度通過 C# 腳本完…

使用 C++ 在當前進程中獲取指定模塊的基址

C 實現 , 獲取指定模塊在該進程中的基址 1、流程: 獲取進程的所有模塊信息–>遍歷模塊列表 2、實現&#xff1a; // 我自己定義的 typedef struct moudle_date_ {HANDLE mhandle; // 句柄char mname[64]; // 名稱char* date; // 數據DWORD mdword; // 基址…

【機器學習】Adaboost: 強化弱學習器的自適應提升方法

&#x1f308;個人主頁: 鑫寶Code &#x1f525;熱門專欄: 閑話雜談&#xff5c; 炫酷HTML | JavaScript基礎 ?&#x1f4ab;個人格言: "如無必要&#xff0c;勿增實體" 文章目錄 Adaboost: 強化弱學習器的自適應提升方法引言Adaboost基礎概念弱學習器與強學習…

存儲器容量小才使用SRAM芯片,容量較大時使用DRAM芯片。為什么?

在計算機系統中&#xff0c;存儲器容量的選擇涉及到多種因素&#xff0c;包括成本、速度和復雜性。SRAM&#xff08;靜態隨機存取存儲器&#xff09;和DRAM&#xff08;動態隨機存取存儲器&#xff09;是兩種常見的內存類型&#xff0c;它們在設計和應用上有顯著的不同。以下是…