C語言:字符函數與字符串函數(1)

在編程的過程中,我們經常會遇到需要處理字符和字符串的情況,為了方便操作字符和字符串,C語言標準庫中提供了一系列庫函數,接下來我們就學習一下這些函數。


目錄

1.?字符分類函數

2. 字母轉換函數

3. strlen函數的使用和模擬實現

4. strcpy函數的使用和模擬實現

5. strcat函數的使用和模擬實現


1.?字符分類函數

C語言中有一系列的函數是專門做字符分類的,也就是?個字符是屬于什么類型的字符的。 這些函數的使用都需要包含一個頭文件是<ctype.h>

一共有下面這些函數,當這些函數處理的字符滿足條件時返回值就為真:

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:任何可打印字符,包括圖形字符和空白字符

這些函數的使用方法非常相似,我們就只列舉一個函數的使用方法:

int islower(int c);

通過返回值來說明是否是小寫字母,如果是小寫字母就返回非0的整數,如果不是小寫字母,則返回0。

例如:將字符串中的小寫字母轉換為大寫字母

#include <ctype.h>
#include <stdio.h>
int main()
{int i = 0;char s[] = "Hello World";while(s[i]){if(islower(s[i]))s[i] -= 32;i++;}printf("%s\n",s);return 0;
}
HELLO WORLD

當返回值為非0值時,將字符的數值減去32,將小寫字母轉換為對應的大寫字母,最后將修改后的字符串打印出來,查看結果是否符合預期。

2. 字母轉換函數

C語言提供了2個字符轉換函數:

int tolower ( int c ); //將參數傳進去的?寫字?轉?寫     
int toupper ( int c ); //將參數傳進去的?寫字?轉?寫

上面的代碼中,我們是利用islower函數來判斷字符是否為小寫字母,若是,則讓其減去32,實現小寫字母轉化為大寫字母的效果。而現在,我們可以直接使用toupper函數將小寫字母轉化為大寫字母,例如:

#include <ctype.h>
#include <stdio.h>
int main()
{int i = 0;char s[] = "Hello World";while(s[i]){if(islower(s[i]))s[i] = toupper(s[i]);i++;}printf("%s\n",s);return 0;
}

3. strlen函數的使用和模擬實現

strlen函數原型為:

 size_t strlen ( const char * str );

字符串以字符'\0'為結束標志,strlenm函數返回的值是字符串中字符'\0'前的字符個數(不包括'\0')

參數指向的字符串必須要以'\0'結束

注意函數的返回值類型為size_t,是無符號的

strlen的使用需要包含頭文件<string.h>

#include <string.h>
#include <stdio.h>
int main()
{char s[] = "Hello World";printf("%d\n", strlen(s));return 0;
}
11

我們在前面指針的內容中就已經講解過怎么模擬實現strlen函數,這里不再重復:

因為會使用到指針,這里加上assert,防止使用空指針

#include <assert.h>
size_t my_strlen(char* s)
{assert(s);size_t len = 0;while(*s++){len++;}return len;
}

這里再給處一種不創建臨時變量的方法:

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

利用遞歸與指針的方式,在不創建臨時變量的情況下,模擬實現strlen函數,不過這種方法的運行效率比較低,運行會上面的代碼慢

4. strcpy函數的使用和模擬實現

strcpy函數的原型為:

char* strcpy(char * destination, const char * source );
Copies the C string pointed by source into the array pointed by destination, including the terminating null character (and stopping at that point).

簡單來說就是將一個字符串的內容復制到另一個字符串中,進行這個操作要滿足這些條件:

源字符串必須以'\0'結尾。

會將源字符串中的'\0'拷貝到目標空間。

目標空間必須足夠大,以確保能存放源字符串。

目標空間必須可修改。

了解這些后,我們可以嘗試將一個字符串的內容復制到另一個字符串中:

#include <string.h>
#include <stdio.h>
int main()
{char s1[20] = "Hello World";char s2[] = "Good morning";printf("%s\n", strcpy(s1,s2));printf("%s\n",s1);return 0;
}
Good morning
Good morning

了解了使用方法后,我們現在來思考如何模擬實現strcpy函數:

由于C語言自帶的strcpy函數無法檢測目標字符串大小是否能夠放下源字符串內容,我們在模擬實現時加上這一步判斷。

首先,我們要讓函數接收目標字符串dest和源字符串src的地址。

接著,我們要保證傳遞的兩個字符串的地址是有效的,我們要使用assert函數;而且,也要保證字符串dest足夠放下字符串src中的內容,那就需要比較兩個字符串的大小。考慮到目標字符串中可能出現'\0'提前出現的情況,我們不能使用strlen來計算目標字符串的大小,因此,我們需要用sizeof來計算目標字符串大小;相對地,源字符串不需要考慮這個問題,但是字符'\0'也是需要占據空間地,因此在比較時需要讓其+1。但是,由于字符數組dest地址在傳遞給函數時會轉化為數組首元素的地址,在函數內部中使用時只能找到該元素而無法找到整個字符數組,因此在傳遞參數時我們還有額外傳遞參數size_dest,用于比較大小。

然后,我們就需要考慮如何將一個字符串的內容復制到另一個字符串中。

這里我們就要使用指針方法逐個訪問字符串dest和src中的內容,并將src中的內容賦值給dest,直到訪問到src中的'\0'。

最后,返回目標字符串的地址,但是現在有個問題,那就是指針dest指向的地址在我們復制操作結束后已經不是指向dest首字符的地址了。因此,我們需要在賦值前創建一個指針變量來存儲該地址,用于最后返回。

分析完畢,代碼形式如下:

char* my_cpy(char* dest,const char* src,size_t size_dest)
{assert(dest && src);if(size_dest < strlen(src) + 1){printf("目標字符串空間大小不足");return NULL;}char* origin_dest = dest;while((*dest++ = *src++));return origin_dest;
}

我們嘗試使用一下函數my_cpy:

int main()
{char s1[20] = "Hello World";char s2[] = "Good morning";printf("%s\n", my_cpy(s1,s2, sizeof(s1)));printf("%s\n",s1);return 0;
}
Good morning
Good morning

我們可以發現,打印結果符合我們預期,代碼成功模擬實現了strcpy函數的效果。

5. strcat函數的使用和模擬實現

函數strcat原型如下:

char *strcat(char *dest, const char *src);
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'結束

目標字符串中也得有'\0',否則無法知道從哪里開始追加

目標空間必須有足夠的大,能容納下源字符串的內容。

目標空間必須可修改。

了解這些后,我們可以嘗試使用一下strcat函數:

#include <string.h>
#include <stdio.h>
int main()
{char s1[20] = "Hello ";char s2[] = "World";printf("%s\n", strcat(s1,s2));printf("%s\n",s1);return 0;
}
Hello World
Hello World

我們可以看到,strcat函數成功將字符串s2的內容追加到了字符串s1末尾。

現在,我們來思考一下如何模擬實現strcat函數:

同樣的,由于C語言自帶的strcat函數無法檢測目標字符串大小是否能夠放下源字符串內容,我們在模擬實現時加上這一步判斷。

首先,我們需要函數接收兩個字符串dest和src的地址,以及字符串dest的大小size_dest。

接著,就是相同的操作,檢驗指針的有效性以及字符串dest的空間是否符合要求。若是條件都滿足,創建一個指針變量來存儲dest的地址。

然后,就是追加的操作,這一步和上面my_cpy的操作一樣。只不過我們需要先找到dest中第一個'\0'的位置,然后再開始追加操作。

最后,返回dest的地址。

代碼形式如下:

char* my_cat(char* dest,const char* src,size_t size_dest)
{assert(dest && src);size_t need = strlen(dest) + strlen(src) + 1;if(size_dest < need){printf("目標空間不足,實際需要空間為%zd\n",need);return NULL;}char* origin_dest = dest;while(*dest) dest++;while((*dest++ = *src++));return origin_dest;
}

我們嘗試使用一下函數my_cat:

int main()
{char s1[20] = "Hello ";char s2[] = "World";printf("%s\n", my_cat(s1,s2, sizeof(s1)));printf("%s\n",s1);return 0;
}
Hello World
Hello World

我們可以發現,打印結果符合我們預期,代碼成功模擬實現了strcat函數的效果。

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

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

相關文章

數據結構與算法系列(大白話模式)小學生起點(一)

出身&#xff0c;并不重要 &#xff01;&#xff01;&#xff01;&#xff01;只要有恒心&#xff0c;有毅力&#xff0c;肯于付出與學習&#xff0c;皆會取得相應的成就&#xff01;天道酬勤&#xff0c;天行健&#xff0c;君子當自強不息&#xff01;道可道&#xff0c;非常道…

計算機視覺第一課opencv(二)保姆級教學

目錄 簡介 一、邊界填充 1.函數說明 2.案例分析 二、圖像運算 1.號運算 2.cv2.add()函數 3.圖像加權運算 三、閾值處理 四、圖像平滑處理 1.椒鹽噪聲 2.均值濾波&#xff08;Mean Filtering&#xff09; 3.方框濾波 4. 高斯濾波&#xff08;Gaussian Filtering&am…

DINOv3

一、摘要 https://arxiv.org/pdf/2508.10104 自監督學習有望消除對人工數據標注的需求&#xff0c;使模型能夠輕松擴展到大規模數據集和更大規模的架構。由于不針對特定任務或領域進行定制&#xff0c;這種訓練范式具有從各種來源學習視覺表示的潛力&#xff0c;能夠使用單一…

??pytest+yaml+allure接口自動化測試框架

高薪必備&#xff01;18K接口自動化測試框架落地全流程&#xff5c;零基礎到實戰通關前言# 自動化測試&#xff0c;是目前測試行業一項比較普遍的測試技術了&#xff0c;之前的以UI自動化測試為主&#xff0c;現在的以接口自動化測試為主&#xff0c;無論技術更迭&#xff0c;…

LeetCode每日一題,2025-8-20

統計全為1的正方形子矩陣 這題是正方形&#xff0c;比較簡單 暴力就是二維前綴和。 或者用dp&#xff0c;dp[i][j]表示以i&#xff0c;j為右下角的最大正方形的邊長&#xff0c;它由(i-1,j),(i,j-1),(i-1,j-1)三者共同決定&#xff0c;通過找規律可知&#xff0c;由三個的最小值…

在Excel啟動時直接打開多個Excel文件

如果我們這段時間每天都要打開幾個相同的Excel文件開展工作&#xff0c;可以把這幾個文件放到一個文件夾&#xff08;如果原來就在不同的文件夾&#xff0c;就把快捷方式放到同一個文件夾&#xff09;&#xff0c;然后在Excel選項中設置啟動時打開這個文件夾中的文件即可。注&a…

對象存儲 COS 端到端質量系列 —— 終端網絡診斷工具

背景 在COS終端SDK的眾多功能中&#xff0c;文件上傳功能的使用頗為頻繁。鑒于此&#xff0c;提升文件上傳的成功率便顯得至關重要。眾多導致上傳失敗的因素里&#xff0c;由網絡問題引發的故障無疑是其中影響上傳成功率的關鍵因素之一&#xff0c;同時也是最難以把控的要素。…

Flask高效數據庫操作指南

Flask-SQLAlchemy 數據庫操作關于Flask數據庫Flask中沒有指定使用的數據庫&#xff0c;可以自由選擇不管你是使用關系型數據庫&#xff0c;還是非關系型數據庫都可以&#xff0c;不像django提供了orm 數據庫抽象層&#xff0c;可以直接采用對象的方式操作數據庫。但是為了開發效…

Camera相機人臉識別系列專題分析之十九:MTK ISP6S平臺FDNode原生代碼

【關注我,后續持續新增專題博文,謝謝!!!】 上一篇我們講了: 這一篇我們開始講: 目錄 一、問題背景 二、MTK ISP6S平臺FDNodeImp.cpp 2.1:原生代碼

S32K3 的圖形化配置和EB配置mcal差異

32K3系列的圖形化配置工具&#xff08;如S32 Design Studio, S32DS&#xff09;與EB配置工具&#xff08;基于EB tresos Studio&#xff09;在配置MCAL&#xff08;Microcontroller Abstraction Layer&#xff09;時存在關鍵差異&#xff0c;主要體現在工具環境、配置流程、代碼…

Meta 再次重組人工智能部門

每周跟蹤AI熱點新聞動向和震撼發展 想要探索生成式人工智能的前沿進展嗎&#xff1f;訂閱我們的簡報&#xff0c;深入解析最新的技術突破、實際應用案例和未來的趨勢。與全球數同行一同&#xff0c;從行業內部的深度分析和實用指南中受益。不要錯過這個機會&#xff0c;成為AI領…

在nodejs中 有哪些是 “假值“和怎么寫 “雙重否定”

1.在 Node.js&#xff08;以及 JavaScript&#xff09;中&#xff0c;以下值在布爾上下文&#xff08;例如 if 語句、while 循環條件等&#xff09;中被視為 “假值”&#xff1a;false&#xff1a;布爾類型的 false 值&#xff0c;這是最直接的假值。if (false) {console.log(…

車載軟件架構 --- 贏得汽車軟件開發競賽

我是穿拖鞋的漢子,魔都中堅持長期主義的汽車電子工程師。 老規矩,分享一段喜歡的文字,避免自己成為高知識低文化的工程師: 做到欲望極簡,了解自己的真實欲望,不受外在潮流的影響,不盲從,不跟風。把自己的精力全部用在自己。一是去掉多余,凡事找規律,基礎是誠信;二是…

機器學習總復習

這段時間學習了 KNN&#xff0c;線性回歸&#xff0c;邏輯回歸&#xff0c;貝葉斯&#xff0c;聚類&#xff08;K-means,DBSCAN&#xff09;&#xff0c;決策樹&#xff0c;集成學習&#xff08;隨機森林&#xff0c;XGboost&#xff09;&#xff0c;SVM支持向量機&#xff0c;…

深入解析EventPoller:Disruptor的輪詢式事件處理機制

EventPoller 是什么&#xff1f;EventPoller 是 Disruptor 框架中一種 基于輪詢&#xff08;poll-based&#xff09; 的事件消費機制。它與我們更常見的 BatchEventProcessor&#xff08;基于獨立的消費者線程&#xff09;形成了對比。核心區別在于&#xff1a;BatchEventProce…

K8S-Secret資源對象

目錄 一、Secret概述 二、Secret 類型 kubectl 創建類型 三、Secret 使用 Opaque 類型 Secret 的使用 創建 yaml 一、Secret概述 k8s secrets用于存儲和管理一些敏感數據&#xff0c;比如密碼&#xff0c;token&#xff0c;密鑰等敏感信息。它把 Pod 想要訪問的加密數據…

lua入門以及在Redis中的應用

1.基本語法1.1變量lua的變量有&#xff1a;無效值nil&#xff0c;布爾值boolean&#xff0c;數字number、字符串string、函數function、自定義類型userdata、線程thread、表table&#xff08;key-value結構&#xff09;1.2循環數值循環for i起始值, 結束值 ,間隔值 do---option…

淘寶電商大數據采集【采集內容||采集方法|工具||合規性||應用】

淘寶電商大數據采集是指通過技術手段、工具或平臺&#xff0c;系統性收集淘寶&#xff08;及旗下天貓等&#xff09;生態內的各類數據&#xff0c;用于分析市場趨勢、用戶行為、商品表現、競品動態等&#xff0c;為電商運營、決策提供數據支持。以下從采集內容、工具方法、合規…

ROS2核心模塊

1.創建工作空間先創建工作空間ws01_plumbing&#xff0c;終端下進入工作空間的src目錄&#xff0c;執行如下命令&#xff1a;ros2 pkg create --build-type ament_cmake base_interfaces_demo2.話題通信話題通信是ROS中使用頻率最高的一種通信模式&#xff0c;話題通信是基于發…

Mac 上安裝并使用 frpc(FRP 內網穿透客戶端)指南

一、先裝好 Homebrew&#xff08;macOS 的包管理器&#xff09;打開終端&#xff08;Terminal&#xff09;&#xff0c;先裝命令行開發工具 xcode-select --install彈窗點“安裝”&#xff0c;等待 3~5 分鐘。一鍵安裝 Homebrew /bin/bash -c "$(curl -fsSL https://raw.g…