一 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");
}