一 C 語言字元處理函數庫 ctype.h
字元處理函數庫(Character-handling library),包含幾個用于字元資料測試和操作的函數。每個函數接受的實參都是一個用整型數或EOF表示的字元。在 C 語言中 字元通常被當作整型數來處理,因為C語言中的字元通常是一個位元組的整數。一般而言, EOF的值為 -1,但是某些硬體體系結構不允許在char類型變量中存儲負值,是以,字元處理函數把這種字元當作整型數來處理。
函數原型 | 描述 |
int isdight(int c) | 如果C是數字,函數傳回真,否則,傳回假(0) |
int isalpha(int c) | 如果C是字母,函數傳回真,否則,傳回假(0) |
int isalnum(int c) | 如果C是數字或字母,函數傳回真,否則,傳回假(0) |
int isxdigit(int c) | 如果C是一個十六進制的數字字元,函數傳回真,否則,傳回假(0) |
int islower(int c) | 如果C是小寫字母,函數傳回真,否則,傳回假(0) |
int isupper(int c) | 如果C是大寫字母,函數傳回真,否則,傳回假(0) |
int tolower(int c) | 如果C是大寫字母,函數将 C 轉換為小寫字母後傳回,否則,傳回未改變實參 C 的值 |
int toupper(int c) | 如果C是小寫字母,函數将 C 轉換為大寫字母後傳回,否則,傳回未改變實參 C 的值 |
int isspace(int c) | 如果c 是空白字元( '\n' ; ' ' ; '\f' ; '\r' ; '\t' ; '\v' ),則函數傳回為真,否則,傳回假(0) |
int iscntrl(int c) | 如果 c 是一個控制符,則函數傳回為真,否則,傳回假(0) |
int ispunct(int c) | 如果 c 是一個除空格,數字,字母以外的所有可列印字元,則函數傳回為真,否則,傳回假(0) |
int isprint(int c) | 如果 c 是一個包含空格在内的可列印字元,則函數傳回為真,否則,傳回假(0) |
int isgraph(int c) | 如果 c 是一個除空格以外的所有可列印字元,則函數傳回為真,否則,傳回假(0) |
示例:
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h> //字元函數頭檔案
void main()
{
char n = '10';
//int n = '8';
int flag = isdigit(n);//isdigit 判斷字元是否是數字
printf("根據 isdigit 函數判斷是否是數字\n ");
if (flag)
{
printf("n='10'-> n是數字\n");
}
else
{
printf("n='10'-> n是不數字\n");
}
printf("\n----------------------\n");
char c1 = 'B';
printf("根據 isalpha 函數判斷是否是字母\n ");
char* str1 = { isalpha(c1) ? "c1='B' c1是字母" : "c1='B' c1不是字母" };
printf("%s \n", str1);
printf("\n----------------------\n");
printf("%s\n%s%s\n%s%s\n%s%s\n%s%s\n",
"According to isalnum:",
isalnum('A') ? "A is a" : "A is not a", "letter",
isalnum('b') ? "b is a" : "b is not a", "letter",
isalnum('#') ? "# is a" : "# is not a", "letter",
isalnum('4') ? "4 is a" : "4 is not a", "letter");
printf("\n----------------------\n");
printf("%s\n%s%s\n%s%s\n%s%s\n%s%s\n",
"根據 isxdigit 函數判斷是否是十六進制字元:",
isxdigit('A') ? "A 是一個" : "A 不是一個", "十六進制字元",
isxdigit('K') ? "K 是一個" : "K 不是一個", "十六進制字元",
isxdigit('E') ? "E 是一個" : "E 不是一個", "十六進制字元",
isxdigit('G') ? "G 是一個" : "G 不是一個", "十六進制字元");
printf("\n----------------------\n");
printf("%s\n%s%s\n%s%s\n",
"根據 islower 函數判斷字元是否是小寫字元:",
islower('A') ? "A 是一個" : "A 不是一個", "小寫字元",
islower('a') ? "a 是一個" : "a 不是一個", "小寫字元");
printf("\n----------------------\n");
printf("%s\n%s%s\n%s%s\n",
"根據 isupper 函數判斷字元是否是大寫字元:",
isupper('A') ? "A 是一個" : "A 不是一個", "大寫字元",
isupper('a') ? "a 是一個" : "a 不是一個", "大寫字元");
printf("\n----------------------\n");
system("pause");
}

二 通用函數庫中字元串轉換函數 stdlib.h:
這些函數将數字字元串轉換為整數或浮點型數值。注意:使用限定符 const 聲明函數頭中的變量 nPtr (從右向左讀,nPtr 是一個指針,指向一個字元常量),const 規定這個實參的值不能被修改。
函數原型 | 函數描述 |
double atof(const char *nPtr) | 将 nPtr 指向的字元串轉換為雙精度浮點數 |
int atoi(const char *nPtr) | 将 nPtr 指向的字元串轉換為整型數 |
long atol(const char *nPtr) | 将 nPtr 指向的字元串轉換為長整型數 |
double strtod(const char *nPtr, char **endPtr) | 将 nPtr 指向的字元串轉換為雙精度浮點數 |
long strtol(const char *nPtr, char **endPtr, int base) | 将 nPtr 指向的字元串轉換為長整型數 |
unsigned long strtoul(const char *nPtr, char **endPtr, int base) | 将 nPtr 指向的字元串轉換為無符号長整型數 |
示例:
#include<stdio.h>
#include<stdlib.h>
void main()
{
double d1 = atof("12.3345");
printf("%s %.4f\n", "字元串:‘12.3345’, 轉換為雙精度浮點類型為:", d1);
printf("\n --------------------- \n");
int n1 = atoi("100");
printf("%s %d\n", "字元串:‘100’, 轉換為整數類型為:", n1);
printf("\n --------------------- \n");
long l1 = atol("1000000000");
printf("%s %d\n%s %d\n", "字元串:‘1000000000’, 轉換為長整數類型為:", l1,"它的2分之一為:",l1/2);
printf("\n --------------------- \n");
const char* str1 = "52.12% abc";
double d2;
char* strPtr1;
d2 = strtod(str1, &strPtr1);
printf("轉換為:%.zf \n剩餘字元串為:%s\n", d2, strPtr1);
printf("\n --------------------- \n");
const char* str2 = "-12399334abc";
char* strPtr2;
long l2;
l2 = strtol(str2, &strPtr2, 0);//參數1 字元串,參數2 剩餘字元串,參數3 轉換後數值可以表示的進制形式(8進制,基數為8;10進制 基數為10 ;16進制 基數為16)這個基數可以指定 0 或2 - 36 之間的任意數
printf("轉換為:%ld \n剩餘字元串為:%s\n", l2, strPtr2);
printf("再加上 %d 後的結構是:%ld \n", 550, l2 + 550);
printf("\n --------------------- \n");
const char* str3 = "123456789NNN";
char* strPtr3;
long l3;
l3 = strtol(str3, &strPtr3, 0);
printf("轉換為:%lu \n剩餘字元串為:%s\n", l3, strPtr3);
printf("再減去 %d 後的結構是:%lu \n", 550, l3 + 550);
printf("\n --------------------- \n");
system("pause");
}
三 字元串處理函數庫 string.h
字元串複制和連接配接函數:
函數原型 | 函數描述 |
char * strcpy ( char *s1 , const char * s2) | 将字元串s2 複制到s1 中,函數傳回s1的值 |
char * strncpy ( char *s1 , const char * s2, size_t n) | 把 s2指向的字元串的 n 個 字元,拷貝到 s1 指向的位置,函數傳回 s1 |
char * strcat ( char *s1 , const char * s2) | 把 s2 指向的字元串拷貝到 s1指向字元串的後面,s2 字元串的第一個字元位置覆寫 s1字元串的空字元位置,函數傳回 s1 |
char * strncat ( char *s1 , const char * s2, size_t n) | 把 s2 指向的字元串的 n 個字元拷貝到 s1指向字元串的後面(或拷貝到s2的空字元為止),s2 字元串的第一個字元位置覆寫 s1字元串的空字元位置,函數傳回 s1 |
示例:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
/*
擷取字元串個數
*/
int countString(char* str)
{
int n = 0;
while (*str!='\0')
{
n++;
str++;
}
return n;
}
int main()
{
printf("******************** 字元串拷貝函數示例 ********************\n\n");
char* str = "Happy Birthday to you";
char str1[50] = {0};
char str2[50] = {0};
printf("%s%s\n%s%s\n", "原字元串str:", str, "拷貝後str1:", strcpy(str1, str));
int num = countString(str);
strncpy(str2, str, num - 7);
//如果字元數組沒有初始化為0 ,保險期間應加上 :str2[num-7]='\0' ,添加字元串結束标記
printf("%s%s\n", "拷貝後str2:", str2);
printf("******************** 字元串拷貝函數示例 ********************\n\n");
printf("******************** 字元串連接配接函數示例 ********************\n\n");
char s1[20] = "Happy ";
char s2[] = "New Year";
char s3[50] = { 0 };
printf("s1=%s\ns2=%s\ns3=%s\n", s1, s2, s3);
printf("strcat(s1,s2)=%s\n", strcat(s1, s2));
printf("strcat(s3,s1,6)=%s\n", strncat(s3, s1,6));
printf("strcat(s3,s1)=%s\n", strcat(s3, s1));
printf("******************** 字元串連接配接函數示例 ********************\n\n");
system("pause");
}
字元串比較函數:
函數原型 | 函數描述 |
int strcmp( const char *s1 , const char *s2) | 比較字元串s1和 s2,當 s1 等于,小于,大于s2時,函數分别傳回 0,1,-1 |
int strncmp( const char *s1 , const char *s2, size_t n) | 比較字元串s1和s2的n個字元,當 s1 等于,小于,大于s2時,函數分别傳回 0,1,-1 |
示例:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
/*
自定義字元串比較函數 ,傳回 int 類型 0 相等 ,!0 不等
*/
int myStrcmp(char *p1, char *p2)
{
int i = 0; //下标,從第一個字元開始比較
//如果相當且沒有結束,就一直向前比較
while (p1[i]==p2[i]&&p1[i]!='\0')
{
i++;//下标向前移動
}
int num;
if (p1[i] == '\0'&&p2[i] == '\0')
{
num = 0;
}
else
{
num = p1[i] - p2[i]; //将內插補點指派num
}
return num;
}
void main()
{
//strncmp :比較字元串前 n 個字元是否相等 ,其他與strcmp相同
char chA[30] = "notepadAAA";
char chB[30] = "notepadSS";
if (strncmp(chA, chB, 7) == 0)
{
printf("%s 和 %s 的前 %d 個字元比較結果是:相等\n", chA, chB,7);
}
else
{
printf("%s 和 %s 的前 %d 個字元比較結構是:不等\n", chA, chB, 7);
}
//strcmp函數: 傳回int類型 相當 =0 大于 =1 小于 =-1 一般用于驗證密碼
char ch1[20] = "Strcmp";
char ch2[20]= "strcmp";
// int num = strcmp(ch1,ch2);
_strupr(ch1); //轉大寫
_strupr(ch2);
int num = myStrcmp(ch1, ch2);
if (num == 0)
{
printf("%s 和 %s 的比較結果是:相等\n",ch1,ch2);
}
else
{
printf("%s 和 %s 的比較結果是:不等\n", ch1, ch2);
}
system("pause");
}
字元串查找函數:
函數原型 | 函數描述 |
char *strchr ( const char *s , int c) | 在 S 所指向的對象中,确定字元C第一次出現的位置。若找到C,函數傳回 S 中 C 的指針,否則傳回NULL |
size_t strcspn( const char *s1, const char *s2 ) | 确定并傳回字元串s1中不包含(未出現)在字元串s2中任何字元的(最大)起始(字元串片段的)長度 |
size_t strspn( const char *s1, const char *s2 ) | 确定并傳回字元串s1中隻包含字元串s2中字元的起始字元串片段的長度 |
char * strbrk( const char *s1, const char *s2 ) | 在字元串s1中,确定字元串s2中字元第一次出現的位置。若找到字元串s2中的字元,函數則傳回指向s1中該字元的指針。否則傳回NULL指針 |
char *strrchr ( const char *s , int c) | 在 S 所指向的對象中,确定字元C 最後一次出現的位置。若找到了C 函數傳回S 中 C 的指針,否則傳回NULL 指針 |
char * strstr( const char *s1, const char *s2 ) | 在字元串 s2 中,确定字元串s1 第一次出現的位置。若找到了字元串,函數傳回s1中的指針,否則傳回NULL指針 |
char * strtok( const char *s1, const char *s2 ) | 連續調用 strtok 函數将字元串s1 分解成若幹“标号” (Token)。------ 一行文本中的邏輯片段,例如單詞。這些邏輯片段是被字元串s2中的字元所分割的。第一次調用 strtok 函數需要包含 s1作為第一個實參。如果後續的 strtok 函數調用任然對同一個字元串标号化,則必須以 NULL 作為第一個實參。每次函數調用都指向目前标号的指針,當函數不在産生新的 标号時,傳回NULL |
示例1:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void show1(char* p, int len);
int indexes(char* p1, char* p2);
int main(void)
{
const char* str = "I Love My Motherland China";
char ch1 = 'M';
char* pch1 = NULL;
printf("------------字元查找函數 strchr -----------------\n\n");
pch1 = strchr(str, ch1);
if (pch1 == NULL)
{
printf("%c ,沒有在字元串“ %s ” 中出現\n",ch1,str);
}
else
{
printf("[%c] ,在字元串“ %s ” 中出現\n", ch1, str);
printf("[%c] ,的指針位址是:%p, 存儲的字元是:%c\n", ch1, pch1,*pch1);
}
printf("\n------------------------------------------------\n\n");
///
printf("------------字元查找函數 strcspn -----------------\n\n");
const char* str1 = "The value is 3.1415926 and so on ...... ......";
char* pstring1 = "1234567890";
unsigned int length1 = strcspn(str1, pstring1);//傳回的隻能是從字元串起始位置開始
printf("字元串“ %s ” 中 沒有包含字元串 “ %s ” 的最大片段長度是:%d\n",str1, pstring1,length1);
printf("字元串:");
show1(str1, length1);
printf("長度是:%u",length1);
printf("\n------------------------------------------------\n\n");
//
printf("------------字元查找函數 strpbrk -----------------\n\n");
const char* str2 = "This is a Test";
const char* str3 = "apple";
char* pch2 = strpbrk(str2, str3);
printf("字元串 [%s] ,中的字元 在字元串 [%s] 中第一個比對的是:%c \n", str3, str2, *pch2);
int n = indexes(str2, pch2);
if (n > 0)
{
printf("字元 【%c】在 【%s】中的位置是:%d \n",*pch2,str2, n);
}
printf("\n------------------------------------------------\n\n");
///
printf("------------字元查找函數 strrchr -----------------\n\n");
char ch2 = 'n';
char* pch3 = strrchr(str, ch2);
if (pch3 != NULL)
{
printf("字元【%c】在字元串【%s】最後出現的位置是【%s】", ch2,str, pch3);
}
printf("\n------------------------------------------------\n\n");
//return 0;
system("pause");
}
//輸出字元串從開始到指定長度
void show1(const char* p, int len)
{
if (len == 0||p==NULL)
{
return;
}
int n = 0;
while (n<len)
{
printf("[%c] ", *p);
p++;
n++;
}
}
//求字元 在字元串中的索引位置
int indexes(char* p1, char* p2)
{
int n = -1;
if (p1 == NULL || p2 == NULL)
{
return n;
}
while (*p1!='\0')
{
n++;
if (*p1 == *p2)
{
return n;
}
p1++;
}
return n;
}
示例2:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(void)
{
printf("------------字元查找函數 strchr -----------------\n\n");
const char* str1 = "The value is 3.1415926,3.1415927";
char* pstring1 = " ehT iseluav";
unsigned int n = strspn(str1, pstring1);
printf("str1 中包含 pstring1 的最大字元串片段長度是: %d \n", n);
printf("\n------------------------------------------------\n\n");
///
printf("------------字元查找函數 strstr -----------------\n\n");
char* str2 = "3.14";
char* pstring2 = strstr(str1, str2);
if (pstring2 != NULL)
{
printf("%s 在 %s \n 第一次出現的位置是: %s\n",str2, str1, pstring2);
}
printf("\n------------------------------------------------\n\n");
///
printf("------------字元串分割函數 strtok -----------------\n\n");
char str3[100] = "This is sentence with 7 tokens";
char* tokenPrt; //聲明建立一個指針
printf("%s 使用空格分割為以下字元串:\n", str3);
tokenPrt = strtok(str3, " ");//使用空格分割 (開始)
while(tokenPrt != NULL)
{
printf("%s\n", tokenPrt);
tokenPrt = strtok(NULL, " "); //繼續使用空格分割字元串 ,繼續分割同一個字元串,第一參數為 NULL
}
printf("\n------------------------------------------------\n\n");
system("pause");
}
字元串處理庫中記憶體函數:
函數原型 | 函數描述 |
void *memcpy(void *s1,const void *s2,size_t n); | 将 s2 中的n個字元複制到s1中,傳回指向目标對象(s1)的指針,如果兩個位置出現重疊,其行為未定義。 |
void *memmove(void *s1,const void *s2,size_t n); | 從s2 中複制n個字元到s1中,其行為與拷貝類似,傳回指向目标對象(s1)的指針。但是出現局部重疊情況,該函數會先把重疊的内容拷貝至臨時變量。 |
void *memcmp(void *s1,const void *s2,size_t n); | 比較s1所指向前n個字元和s2所指向的前n個字元,每個值解釋未 char 類型,如果 n 個字元都比對,則完全相同,函數傳回 0 ,如果s1 小于 s2 函數傳回值 <0 , 反之 >0 |
void *memchr(const void *s, int c ,size_t n); | 在 s 所指向的前 n 個字元中,确定 c 第一次出現的位置。若找到 c 傳回指向 c 的指針,否則傳回NULL |
void *memset void *s, int c ,size_t n); | 将 C (無符号 char)複制到 s 所指向前 n 個字元中,傳回指向目标對象(s)的指針 |
示例:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(void)
{
char s1[30] = { 0 };
char s2[30] = "Copy this string";
unsigned int len1 = sizeof("Copy this string");
printf("s1=%s ;s2=%s\n", s1, s2);
printf("拷貝後 s1=%s\n", (char *)memcpy(s1, s2,len1));//如果 s1 沒有初始化為0 長度=len1+1(包含結束标志)
printf("\n------------------------------------------------\n\n");
char s3[] = "Home Sweet Home";
char s4[] = "I Love My Motherland China";
printf("複制之前:%s\n", s3);
printf("複制之後:%s\n", (char*) memmove(s3, &s3[5], 10));//複制到s3 從開始位置起,到指定長度結束,覆寫原有的字元
printf("複制之前:%s\n", s4);
printf("複制之後:%s\n", (char*) memmove(s4, &s3[5], 10));//複制到s4 從開始位置起,到指定長度結束,覆寫原有的字元
printf("\n------------------------------------------------\n\n");
char str1[] = "ABCDEFG";
char str2[] = "ABCDXYZ";
printf("比較兩個字元串的前 n 個字元:\n str1=%s\nstr2=%s\n", str1, str2);
printf("memcmp(str1,str2,4)=%2d\nmemcmp(str1,str2,7)=%2d\nmemcmp(str2,str1,7)=%2d\n",
memcmp(str1, str2, 4),
memcmp(str1, str2, 7),
memcmp(str2, str1, 7));//字元排序越靠後,越大
printf("\n------------------------------------------------\n\n");
char str3[] = "This is a string";
char ch = 's';
unsigned int count = sizeof("This is a string");
char* p =(char *) memchr(str3, ch, count);
if (p != NULL)
{
printf("%c 在 %s 中找到,位址=%p \n", ch, str3,p);
}
printf("\n------------------------------------------------\n\n");
char str[30] = "AAAAAAAAAAAAAAAAAAAA";//這裡不能用字元串指針,數組可以改變元素的值,而字元串指針不可以
printf("原字元串 str=%s\n", str);
printf("複制後 str=%s\n", (char *)memset(str, 'a', 10));
system("pause");
}
其他函數:
函數原型 | 函數描述 |
char *strerror( int errornum) | 将錯誤号 errornum 以位址方式映射成(資訊可能因為位址不同而以不同的語言出現)一個純文字字元串,傳回指向這個字元串的指針 |
size_t strlen ( const char *s) | 擷取 字元串 s 的長度,傳回字元串 結束符号 NULL(‘ \0 ‘)前面的字元個數。 |
示例:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void main()
{
//周遊錯誤資訊
for (int i = 0; i < 10; i++)
{
printf("%d : %s\n", i, strerror(i));
}
printf("\n------------------------------------------------\n\n");
char* str1 = "AAAAAAAAAA";
char str2[] = "This is a string";
char str3[10] = "string";
printf("%s\"%s\"%s%u\n%s\"%s\"%s%u\n%s\"%s\"%s%u\n",
"The lenght of",str1," is ",(unsigned int )strlen(str1),
"The lenght of", str2, " is ", (unsigned int)strlen(str2),
"The lenght of", str3, " is ", (unsigned int)strlen(str3));
system("pause");
}