【C語言】字符函數與字符串函數詳解

文章目錄

  • 一、字符分類函數
  • 二、字符轉換函數
  • 三、strlen函數:計算字符串長度
    • 功能說明
    • 使用示例
    • 模擬實現
  • 四、strcpy函數:字符串拷貝
    • 功能說明
    • 模擬實現
  • 五、strcat函數:字符串追加
    • 功能說明
    • 模擬實現
  • 六、strcmp函數:字符串比較
    • 比較規則
    • 模擬實現
  • 七、strncpy函數:指定長度的字符串拷貝
    • 功能說明
  • 八、strncat函數:指定長度的字符串追加
    • 功能說明
  • 九、strncmp函數:指定長度的字符串比較
    • 功能說明
  • 十、strstr函數:查找子字符串
    • 功能說明
    • 模擬實現
  • 十一、strtok函數:字符串分割
    • 功能說明
  • 十二、strerror函數:獲取錯誤信息
    • 功能說明
    • 相關函數:perror

在C語言編程中,字符和字符串的處理是非常基礎且重要的操作。C語言標準庫提供了一系列專門用于處理字符和字符串的庫函數,掌握這些函數能極大地提高編程效率。本文將詳細介紹這些函數的使用方法和模擬實現,幫助大家深入理解并靈活運用。

一、字符分類函數

字符分類函數用于判斷一個字符屬于哪種類型,它們都包含在ctype.h頭文件中。這些函數的參數為 int類型 , 返回值為 非0(真)或0(假)

以下是常用的字符分類函數及其功能:

  • iscntrl:判斷是否為控制字符
  • isspace:判斷是否為空白字符(空格' '、換頁'\f'、換行'\n'、回車'\r'、制表符'\t'、垂直制表符'\v'
  • isdigit:判斷是否為十進制數字(0~9)
  • isxdigit:判斷是否為十六進制數字(0~9、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:判斷是否為任何可打印字符(包括圖形字符和空白字符)

示例:使用islower函數
islower函數用于判斷參數是否為小寫字母,是則返回非0整數,否則返回0。

下面的代碼將字符串中的小寫字母轉換為大寫,其他字符不變:

#include <stdio.h>
#include <ctype.h>
int main ()
{int i = 0;char str[] = "Test String.\n";char c;while (str[i]){c = str[i];if (islower(c)) c -= 32;putchar(c);i++;}return 0;
}

二、字符轉換函數

C語言提供了兩個常用的字符轉換函數,同樣包含在ctype.h頭文件中:

  • int tolower(int c):將大寫字母轉換為小寫
  • int toupper(int c):將小寫字母轉換為大寫

示例:使用toupper函數
將上面的小寫轉大寫代碼用toupper函數改寫:

#include <stdio.h>
#include <ctype.h>
int main ()
{int i = 0;char str[] = "Test String.\n";char c;while (str[i]){c = str[i];if (islower(c)) c = toupper(c);putchar(c);i++;}return 0;
}

三、strlen函數:計算字符串長度

strlen函數用于計算字符串的長度,其原型為:
size_t strlen(const char *str);

功能說明

  • 字符串以’\0’作為結束標志,strlen返回的是’\0’前面的字符個數(不包含’\0’)
  • 參數指向的字符串必須以’\0’結束
  • 返回值為size_t(無符號整數),這一點在使用時容易出錯

使用示例

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

注意:由于strlen返回值是無符號數,上面代碼中strlen(str2)-strlen(str1)的結果是無符號數,可能會出現與預期不符的情況。

模擬實現

strlen有多種模擬實現方式:

  1. 計數器方式
int my_strlen(const char *str)
{int count = 0;assert(str); // 確保指針非空while(*str){count++;str++;}return count;
}
  1. 遞歸方式(不創建臨時變量)
int my_strlen(const char *str)
{assert(str);if(*str == '\0')return 0;elsereturn 1 + my_strlen(str + 1);
}
  1. 指針-指針方式
int my_strlen(char *s)
{assert(s);char *p = s;while(*p != '\0')p++;return p - s;
}

四、strcpy函數:字符串拷貝

strcpy函數用于將源字符串拷貝到目標空間,原型為:
char* strcpy(char *destination, const char *source);

功能說明

  • 源字符串必須以’\0’結束
  • 會將源字符串中的’\0’拷貝到目標空間
  • 目標空間必須足夠大,以容納源字符串
  • 目標空間必須可修改

模擬實現

char *my_strcpy(char *dest, const char*src)
{char *ret = dest;assert(dest != NULL);assert(src != NULL);while((*dest++ = *src++)){;}return ret;
}

實現說明:循環中先將*src賦值給*dest,然后兩者都自增,直到拷貝到’\0’時,循環條件為假,結束循環。

五、strcat函數:字符串追加

strcat函數用于將源字符串追加到目標字符串末尾,原型為:
char *strcat(char *destination, const char *source);

功能說明

  • 源字符串必須以’\0’結束
  • 目標字符串也必須以’\0’結束,否則無法確定追加的起始位置
  • 目標空間必須足夠大,能容納源字符串的內容
  • 目標空間必須可修改
  • 字符串不能自己給自己追加,會導致錯誤

模擬實現

char *my_strcat(char *dest, const char*src)
{char *ret = dest;assert(dest != NULL);assert(src != NULL);// 找到目標字符串的結束標志'\0'while(*dest){dest++;}// 追加源字符串while((*dest++ = *src++)){;}return ret;
}

六、strcmp函數:字符串比較

strcmp函數用于比較兩個字符串的大小,原型為:
int strcmp(const char *str1, const char *str2);

比較規則

  • 從第一個字符開始比較,若相等則繼續比較下一對字符,直到字符不同或遇到’\0’
  • 標準規定:
    • 第一個字符串大于第二個字符串,返回大于0的數字
    • 兩個字符串相等,返回0
    • 第一個字符串小于第二個字符串,返回小于0的數字
  • 比較的是對應位置字符的ASCII碼值

模擬實現

int my_strcmp(const char *str1, const char *str2)
{assert(str1 != NULL);assert(str2 != NULL);while(*str1 == *str2){if(*str1 == '\0')return 0;str1++;str2++;}return *str1 - *str2;
}

七、strncpy函數:指定長度的字符串拷貝

strncpy函數可以指定拷貝的字符個數,原型為:
char *strncpy(char *destination, const char *source, size_t num);

功能說明

  • 拷貝num個字符從源字符串到目標空間
  • 如果源字符串的長度小于num,則拷貝完源字符串后,在目標空間后追加0,直到達到num個字符

八、strncat函數:指定長度的字符串追加

strncat函數用于將源字符串的前num個字符追加到目標字符串,原型為:
char *strncat(char *destination, const char *source, size_t num);

功能說明

  • 將源字符串的前num個字符追加到目標字符串末尾,并追加一個’\0’
  • 如果源字符串的長度小于num,則只追加到源字符串的’\0’為止

使用示例

#include <stdio.h>
#include <string.h>
int main ()
{char str1[20];char str2[20];strcpy(str1,"To be ");strcpy(str2,"or not to be");strncat(str1, str2, 6);printf("%s\n", str1); // 輸出 "To be or not"return 0;
}

九、strncmp函數:指定長度的字符串比較

strncmp函數用于比較兩個字符串的前num個字符,原型為:
int strncmp(const char *str1, const char *str2, size_t num);

功能說明

  • 比較兩個字符串的前num個字符
  • 如果相等則繼續比較,最多比較num個字符
  • 如果提前發現不同,則提前結束比較
  • 返回值規則與strcmp相同
返回值說明
<0第一個不匹配的字符在str1中的值小于在str2中的值
0兩個字符串的前num個字符相等
>0第一個不匹配的字符在str1中的值大于在str2中的值

十、strstr函數:查找子字符串

strstr函數用于查找一個字符串在另一個字符串中第一次出現的位置,原型為:
char *strstr(const char *str1, const char *str2);

功能說明

  • 返回字符串str2在字符串str1中第一次出現的位置的指針
  • 如果str2不是str1的一部分,則返回空指針
  • 匹配過程不包含’\0’,以’\0’作為結束標志

使用示例

#include <stdio.h>
#include <string.h>
int main ()
{char str[] = "This is a simple string";char *pch;pch = strstr(str, "simple");strncpy(pch, "sample", 6);printf("%s\n", str); // 輸出 "This is a sample string"return 0;
}

模擬實現

char *strstr(const char *str1, const char *str2)
{char *cp = (char *)str1;char *s1, *s2;if (!*str2)return (char *)str1;while (*cp){s1 = cp;s2 = (char *)str2;while (*s1 && *s2 && !(*s1 - *s2)){s1++;s2++;}if (!*s2)return cp;cp++;}return NULL;
}

十一、strtok函數:字符串分割

strtok函數用于分割字符串,原型為:
char *strtok(char *str, const char *sep);

功能說明

  • sep參數是一個字符串,定義了用作分隔符的字符集合
  • 第一個參數為str時,函數找到str中的第一個標記,并用’\0’結尾,返回指向該標記的指針,同時保存該位置
  • 第一個參數為NULL時,函數從上次保存的位置繼續查找下一個標記
  • 如果沒有更多標記,返回NULL
  • strtok會修改被操作的字符串,所以通常對字符串的臨時拷貝進行操作

使用示例

#include <stdio.h>
#include <string.h>
int main()
{char arr[] = "192.168.6.111";char* sep = ".";char* str = NULL;for (str = strtok(arr, sep); str != NULL; str = strtok(NULL, sep)){printf("%s\n", str);}return 0;
}
// 輸出:
// 192
// 168
// 6
// 111

十二、strerror函數:獲取錯誤信息

strerror函數用于獲取錯誤碼對應的錯誤信息,原型為:
char *strerror(int errnum);

功能說明

  • 參數errnum為錯誤碼,函數返回該錯誤碼對應的錯誤信息字符串的地址
  • 錯誤碼通常定義在errno.h頭文件中
  • 程序啟動時,errno(記錄當前錯誤碼的變量)為0,表示沒有錯誤
  • 當標準庫函數發生錯誤時,會將對應的錯誤碼存入errno

使用示例

  1. 打印0~10的錯誤碼對應的信息
#include <errno.h>
#include <string.h>
#include <stdio.h>
int main()
{int i = 0;for (i = 0; i <= 10; i++) {printf("%s\n", strerror(i));}return 0;
}

在Windows11+VS2022環境下的輸出如下:

No error
Operation not permitted
No such file or directory
No such process
Interrupted function call
Input/output error
No such device or address
Arg list too long
Exec format error
Bad file descriptor
No child processes
  1. 在文件操作中使用
#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;
}
// 輸出:Error opening file unexist.ent: No such file or directory

相關函數:perror

perror函數可以直接打印錯誤信息,它會先打印參數中的字符串,再打印一個冒號和空格,最后打印錯誤信息。

#include <stdio.h>
#include <errno.h>
int main ()
{FILE *pFile;pFile = fopen("unexist.ent", "r");if (pFile == NULL)perror("Error opening file unexist.ent");return 0;
}
// 輸出:Error opening file unexist.ent: No such file or directory

本文詳細介紹了C語言中常用的字符函數和字符串函數,包括它們的功能、使用方法和模擬實現。這些函數在日常編程中非常實用,掌握它們能幫助我們更高效地處理字符和字符串操作。在使用過程中,要注意各個函數的參數要求和返回值特點,避免出現不必要的錯誤。

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

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

相關文章

uvicorn 啟動重復加載 多次加載

目錄 uvicorn 啟動重復加載 多次加載 解決方法1&#xff1a; 解決方法2&#xff1a; uvicorn 啟動重復加載 多次加載 fastapi_aa 是當前類 解決方法1&#xff1a; import uvicornfrom fastapi import FastAPIapp FastAPI()if __name__ "__main__":if sys.gett…

Bard AI本地部署教程:在自己的服務器上運行谷歌AI

Bard AI本地部署教程:在自己的服務器上運行谷歌AI 關鍵詞:Bard AI、本地部署、服務器、谷歌AI、運行教程 摘要:本文旨在為大家詳細介紹如何在自己的服務器上實現Bard AI的本地部署。我們會從背景知識講起,逐步深入到核心概念、算法原理、操作步驟,還會提供項目實戰案例和實…

應急響應處置案例(上)

本文目錄 目錄 本文目錄 Web安全事件 概述 案例1 - webshell 背景 排查情況 天眼 服務器 案例2 - Struts2 排查情況 天眼 服務器 案例3 - Redis未授權 背景 排查情況 天眼 服務器 案例4 - EW內網穿透 背景 排查情況 天眼 服務器 案例5 - 一句話木馬 背…

面試官問我:“為什么不能完全用對象替代指針?”我笑了:看看Google和Linux內核代碼就知道了!

本篇摘要 本篇將以最通俗易懂的語言&#xff0c;形象的講述為什么很多情境下&#xff0c;我們優先考慮的使用指針而不是對象本身&#xff0c;本篇將給出你答案&#xff01; 一.從一個生活例子說起&#xff0c;形象秒懂 想象一下&#xff0c;你去圖書館借書&#xff0c;下面你…

CAMx大氣污染模擬全流程:Linux編譯/多重嵌套配置/SMOKE清單預處理/SA-DDM-PA工具應用與科研繪圖結果可視化分析

CAMx模型是一個基于大氣化學&#xff0c;針對臭氧、顆粒物和霧霾天氣過程的大氣污染物計算模型。【目標】&#xff1a;1、掌握CAMx模式的區域空氣質量模擬案例配置技術方法2、掌握SMOKE模型的CAMx模式大氣排放清單輸入準備方法3、掌握CAMx模式污染來源解析工具&#xff08;SA&a…

嵌入式學習筆記-MCU階段-DAY10ESP8266模塊

1.ESP8266概述 官方網址&#xff1a;ESP8266 Wi-Fi MCU I 樂鑫科技 (espressif.com.cn) ESP8266模塊---wifi模塊 產品特點&#xff1a; 2.ESP8266中的wifi: ESP8266EX ?持 TCP/IP 協議&#xff0c;完全遵循 802.11 b/g/n WLAN MAC 協議&#xff0c;?持分布式控制功能 (DC…

如何快速通過軟件項目驗收,第三方軟件檢測機構的重要性

在客戶和開發團隊之間&#xff0c;最后臨門一腳的項目驗收環節總容易出現各種問題&#xff0c;以至于時間無限拉長&#xff0c;久久不見結束&#xff0c;為此給大家準備了一份如何快速通過軟件項目驗收的內容來幫助大家結束持久戰。 一、項目驗收準備材料 &#xff08;一&…

洛谷做題3:P5711 【深基3.例3】閏年判斷

文章目錄題目描述輸入格式輸出格式輸入輸出樣例分析代碼題目描述 輸入一個年份&#xff0c;判斷這一年是否是閏年&#xff0c;如果是輸出 1&#xff0c;否則輸出 0。 1582 年以來&#xff0c;閏年的定義&#xff1a; 普通閏年&#xff1a;公歷年份是 4 的倍數&#xff0c;且不…

PMP證書可以掛靠嗎?怎么掛靠?

哈嘍學弟學妹們&#xff0c;作為過來人&#xff0c;今天想跟大家聊聊 PMP 證書掛靠這事兒 —— 可能不少準備考或者剛考完的同學都琢磨過&#xff0c;但學長得跟你們交個底&#xff1a;這事兒真不行&#xff0c;更別提啥掛靠費了。先說說 PMP 證書本身哈&#xff0c;它是美國 P…

91-基于Spark的空氣質量數據分析可視化系統

基于Spark的空氣質量數據分析可視化系統設計與實現 項目概述 本項目是一個基于Apache Spark的大數據分析和可視化系統&#xff0c;專門用于空氣質量數據的采集、分析、預測和可視化展示。系統采用分布式計算架構&#xff0c;結合機器學習算法&#xff0c;實現了對全國12個主要…

leetcode 2419. 按位與最大的最長子數組 中等

給你一個長度為 n 的整數數組 nums 。考慮 nums 中進行 按位與&#xff08;bitwise AND&#xff09;運算得到的值 最大 的 非空 子數組。換句話說&#xff0c;令 k 是 nums 任意 子數組執行按位與運算所能得到的最大值。那么&#xff0c;只需要考慮那些執行一次按位與運算后等于…

Git 命令使用指南:從入門到進階

目錄1. Git 基本操作1.1 添加文件到暫存區1.2 提交更改到本地倉庫1.3 查看工作區狀態1.4 查看提交歷史1.5 查看引用日志&#xff08;包括已刪除的記錄&#xff09;2. 版本回退與撤銷2.1 版本回退2.2 查看已刪除的提交記錄3. 分支管理3.1 查看分支3.2 創建并切換到新分支3.3 合并…

SQL數據庫連接Python實戰:疫情數據指揮中心搭建指南

SQL數據庫連接Python實戰&#xff1a;疫情數據指揮中心搭建指南從WHO數據集到實時儀表盤&#xff0c;構建工業級疫情監控系統一、疫情數據指揮中心&#xff1a;全球健康危機的中樞神經??疫情數據價值??&#xff1a;全球每日新增病例&#xff1a;50萬疫苗接種數據&#xff1…

參賽單位條件放寬!2025年“數據要素 ×”大賽福建分賽廈門賽區賽事有新調整

各位伙伴們 想抓住數據價值機遇 在行業賽場上嶄露頭角嗎&#xff1f; 2025年“數據要素”大賽 福建分賽廈門賽區已啟動 這份超全賽事解讀 帶你一站式摸清參賽關鍵&#xff01; 01 參賽單位要求放寬 經省分賽組委會與國家賽事組委會溝通&#xff0c;不具有獨立法人資格的…

BasicAuthenticationFilter處理 HTTP 基本認證(Basic Authentication)的核心過濾器詳解

BasicAuthenticationFilter處理 HTTP 基本認證&#xff08;Basic Authentication&#xff09;的核心過濾器詳解在 Spring Security 中&#xff0c;BasicAuthenticationFilter 是??處理 HTTP 基本認證&#xff08;Basic Authentication&#xff09;的核心過濾器??&#xff0…

Next.js 中使用 MongoDB 完整指南

1. 安裝依賴npm install mongodb # 或者使用 mongoose&#xff08;ODM&#xff09; npm install mongoose2. 數據庫連接配置使用原生 MongoDB 驅動創建 lib/mongodb.js 文件&#xff1a;import { MongoClient } from mongodbconst uri process.env.MONGODB_URI const options …

嵌入式系統教學范式演進:云端仿真平臺如何重構溫濕度監測實驗教學

在嵌入式系統開發的教學中&#xff0c;環境溫濕度監測實驗是經典的入門項目。它涉及傳感器原理、外設驅動、數據采集和通信協議等核心知識點。然而傳統實驗模式面臨硬件成本高、調試周期長、設備易損壞等痛點。學生往往因接線錯誤或代碼bug導致傳感器或開發板燒毀&#xff0c;不…

1.6萬 Star 的流行容器云平臺停止開源

什么是 KubeSphere &#xff1f; KubeSphere 是面向云原生應用的容器混合云。 KubeSphere 愿景是打造一個以 Kubernetes 為內核的云原生分布式操作系統&#xff0c;它的架構可以非常方便地使第三方應用與云原生生態組件進行即插即用&#xff08;plug-and-play&#xff09;的集成…

廣東省省考備考(第六十三天8.1)——資料分析、數量(強化訓練)

資料分析 錯題解析解析解析今日題目正確率&#xff1a;80% 數量關系&#xff1a;數學運算 錯題解析解析標記題解析解析解析今日題目正確率&#xff1a;87%

Agents-SDK智能體開發[3]之多Agent執行流程

文章目錄說明Agents SDK基礎Handoffs功能實現Handoffs簡單示例&#x1f31f; 運行結果整理&#x1f4dd; 執行過程概述&#x1f4cb; 運行結果事件一&#xff1a;分診智能體創建轉交請求事件事件二&#xff1a;轉交響應事件事件三&#xff1a;目標 Agent 響應請求并完成任務改進…