【C语言】一篇带你高强度解析精通 字符串函数和内存函数 (万字总结大全,含思维导图)(建议收藏!!!)

【 库函数】——字符串函数和内存函数

目录

思维导图:

一:字符串函数

1.1:字符串常规函数

1.1.1:长度不受限制的字符串函数

1.1.1.1:strlen函数

1.1.1.2:strcpy函数

1.1.1.3:strcat函数

1.1.1.4:strcmp函数

1.1.2:长度受限制的字符串函数

1.1.2.2:strncpy函数

1.1.2.3:strncat函数

1.1.2.4:strncmp函数

1.2:字符串非常规函数

1.2.1:strstr 字符串函数

1.2.2:strtok 字符串函数

1.2.3:strerror 字符串函数

二:内存函数

2.1:memcpy内存函数

2.2:memmove内存函数

2.3:memcmp内存函数

2.4:memset内存函数

三:特殊字符函数

3.1:字符分类函数

3.1.1:isspace函数

3.1.2:isdigit函数

3.1.3:islower函数

3.1.4:isupper函数

3.1.5:isalpha函数

3.1.6:isalnum函数

3.2:字符转换函数

3.2.1:tolower函数

3.2.2:toupper函数


思维导图:

一:字符串函数

1.1:字符串常规函数

1.1.1:长度不受限制的字符串函数

1.1.1.1:strlen函数

函数简介:

函数解析: 

  • 字符串将 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包含 '\0' )
  • 参数指向的字符串必须要以 '\0' 结束。
  • 函数的返回值为size_t,是无符号的。
  • 函数的传参传的是一个地址。
  • strlen 函数属于 string 库中的一个函数,所以在使用 strlen 函数时,要包含这一个库。(#include<string.h>

函数使用:

#include<stdio.h>
#include<string.h>

int main()
{
	// strlen:求字符串长度
	// size_t strlen(const char* str);
	char arr[] = "abcdefg";
	int len = strlen(arr);
	printf("len = %d\n", len);
    return 0;
}

// 打印结果:len = 7

函数分析:

发现,在 arr字符数组中 arr:[ 'a' , 'b' , 'c' , 'd' , 'e' , 'f' , 'g' , '\0' ],注意:'\0' 是此字符串的结束标志,求长度的时候并不将它计算在内,即strlen 函数求的的 '\0' 之前字符的个数。 

模拟实现 strlen 函数:

// 模拟实现 strlen 函数:
int my_strlen(const char* str)
{
	char* s = str;    // 字符指针s 指向数组的第一个字符 'a'
	int count = 0;    // 计数变量 count
	while (*s)        // 判断指针s 指向的是否是 '\0',若是则 *s==0(判断为假,退出循环)
	{
		count++;      // 指针指向的不是 '\0',计数变量加1
		s++;          // 指针指向的不是 '\0',指针s向后移一位
	}
	return count;     // 返回 count 计数变量的值 
}

检查模拟实现的 strlen 函数:

1.1.1.2:strcpy函数

函数简介:

 函数介绍:

  • destination(目标空间),source(源字符串)
  • 源字符串必须以 '\0' 结束。
  • 会将源字符串中的 '\0' 拷贝到目标空间。
  • 目标空间必须足够大,以确保能存放源字符串。
  • 目标空间必须可变
  • 此函数返回的是目标空间的起始地址

通俗的讲:将source字符串拷贝到destination数组空间内。 

实例:

#include<stdio.h>
#include<string.h>

int main()
{
	// strcpy:字符串的拷贝
	// char* strcpy(char* dest,const char* src)
	char arr[] = "abcdefg";
	char arr1[20] = { 0 };
	char* p = strcpy(arr1, arr);
	printf("arr1 = %s\n", arr1);
	printf("p = %s\n", p);
    return 0;
}

打印结果:
// arr1 = abcdefg
// p = abcdefg

 对实例进行分析:其中 arr字符数组(字符串)为源字符串,arr1字符数组是目标空间,strcpy函数的作用就是将arr字符串内容拷贝到 arr1 字符数组中,使得 arr1字符数组空间内含 "abcdefg"。注意:arr1 的数组空间必须要大于被拷贝的内容。

函数没有运行前:各个数组在内存中的信息

 函数运行后:各个数组在内存中的信息

模拟实现 strcpy 字符串函数:

模拟实现 strcpy 字符串拷贝函数

要点一:源字符串中内容不变。

要点二:函数返回的是目标空间的起始地址。

实现:

// 模拟实现 strcpy 函数
char* my_strcpy(char* dest, const char* src)
{
	assert(dest && src);            // 此处为断言,判断源字符空间和目标空间是否为空,为空则报错,这里不做讲解。
	char* ret = dest;               // 先将目标空间的起始地址保存下来

	while (*src)                    // 判断 src指针是否走到 '\0' 的位置,是则退出循环
	{
		*dest = *src;               // 将 src 指针指向的字符赋给 dest 指针指向的位置
        ++dest;                     // dest指针+1      
        ++src;                      // src指针+1
	}
    *dest = *src;                    // 将 '\0' 赋给 dest指针 指向的空间

	return ret;                      // 返回ret(目标空间的起始地址)
}

 查看模拟情况:

模拟成功! 

1.1.1.3:strcat函数

函数简介:

函数介绍:

strcat :字符串连接函数

其功能就是将两个字符串连接起来。" char* strcat(char* destination, const char* source) ",将source指针指向的字符串连接到 destination 指向的字符串的后面,即例如:destination指针指向的字符串是 hello ,source 指针指向的字符串是 china,那么经过此函数调用之后,destination 指针指向的字符串就是 hellochina。

注意:

  • 源字符串必须以 ' \0 ' 结束。
  • 目标空间必须有足够的大,能容纳的下源字符串的内容。
  • 目标空间必须可修改。

 函数使用实例:

#include<stdio.h>
#include<string.h>

int main()
{
    // strcat 字符串连接函数
    // char* strcat(char* destination, const char* source)
    char arr[30] = "hello ";
    char arr1[] = "china";
    char* p = strcat(arr,arr1);
    printf("p = %s\n",p);
    printf("arr = %s\n",arr);
    return 0;
}

// 打印结果:
// p = hello china
// arr = hello china

分析:

函数运行前字符数组在内存中的情况:

函数运行后字符数组在内存中的情况: 

 发现,在函数运行之后在 arr字符串之后添加了arr1字符串的内容,并且 arr1 中的内容没有变化。

模拟实现 strcat 字符串连接函数:

步骤一:先将 arr 字符串的首元素的地址存起来。

步骤二:使用指针找到 arr 字符串的 ' \0 ' 位置处。

步骤三:再将 arr1字符串的内容拷贝到 arr字符串的 ' \0 ' 的位置上。

 实现:

// 模拟实现 strcat 函数
char* my_strcat(char* dest, const char* src)
{
	assert(dest && src);                // 断言
	char* ret = dest;                   // 存目标空间的首地址

	while (*dest)                       // 检查 dest 指针指向的字符是否是 '\0',是则退出循环
	{
		dest++;        
	}
	while (*src)                        // 检查 src 指针是否拷贝到 '\0' 这个位置。是就结束
    {
        *dest = *src;
        ++dest;
        ++src;
    }
    *dest = *src;                        // 将源字符串的最后一个字符'\0'拷贝到目标空间中
	return ret;                          // 返回目标空间的首地址
}

检查自我模拟的字符串连接函数:

运行前字符数组内存情况:

 运行后字符数组内存情况:

模拟成功!

1.1.1.4:strcmp函数

函数简介:

函数介绍:

strcmp:字符串比较函数,即比较两个字符串的大小。

  • 此函数开始比较每个字符串的第一个字符。如果它们彼此相等,则继续执行以下对,直到字符不同或达到终止 ' \0 ' 字符。 
  • 标准规定:
    第一个字符串大于第二个字符串,则返回大于 0 的数字
    第一个字符串等于第二个字符串,则返回 0
    第一个字符串小于第二个字符串,则返回小于 0 的数字
官方叙述:

函数实例:

#include<stdio.h>
#include<string.h>

int main()
{
	// strcmp:字符串的比较
	char a[] = "abcd";
	char b[] = "abcdef";
	int x = strcmp(a, b);
    // 比较各个相应字符的ASCII码值
	// a > b  -->  1
	// a = 0  -->  0
	// a < b  -->  -1
	printf("x = %d\n", x);
    return 0;
}

// 打印结果:
// x = -1

分析:a字符串中内容 "abcd",b字符串中内容 "abcdef"。先开始比较每个字符串的第一个字符,因为它们第一个字符都是 'a',相等。在继续执行两个字符串的第二个字符,相等则继续执行,当执行到第五个字符时,a[4] = '\0',b[4] = 'e',字符e的ACSII码值大于'\0'的ACSII码值,所以b字符串大于 a 字符串。返回一个小于0的数,一般就是 -1。

模拟strcmp字符串比较函数:

// 模拟实现 strcmp 函数
int my_strcmp(const char* str1, const char* str2)
{
	assert(str1 && str2);            // 断言(检查是否有错误)

	while (*str1 == *str2)           // 检查对应字符是否相等
	{
		++str1;                      // 相应字符相等,指针+1,往后移一位
		++str2;
		if (*str1 == '\0')           // 如果一个字符串遇到'\0'结束了 ,就退出循环	
        {
			break;
		}
	}

	if (*str1 > *str2)            // 判断对应的两个字符谁大谁小
	{
		return 1;                    // 第一个字符大就返回1
	}
	else if (*str1 < *str2)
	{
		return -1;                // 第二个字符大就返回-1
	}
	else
		return 0;                 // 两个字符相等就返回0
}

检查模拟的函数是否正确:

模拟函数成功!

1.1.2:长度受限制的字符串函数

所谓长度受限制,就是当使用字符串函数操作字符串时,并不仅仅直接操作整个字符串,而是操作字符串中的 n 个字符。

1.1.2.2:strncpy函数

函数简介:

函数介绍:

  •  strncpy :特殊的字符串拷贝函数
  • "char* strncpy( char* destination, const char* source, size_t num)"
  • 从source字符串从前往后取出 num 个字符拷贝到destination字符空间内。
  • 如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。

函数使用实例:

#include<stdio.h>
#include<string.h>

int main()
{
	// strncpy:长度受限制的字符串拷贝
	// char* strncpy(char* dest,const char* src,size_t num)
	char arr[] = "abcdef";
	char arr1[30] = { 0 };
	char* p = strncpy(arr1, arr, 2);
	printf("p = %s\n", p);
	printf("arr1 = %s\n", arr1);
    return 0;
}

// 打印结果:
// p = ab
// arr1 = ab

 分析:长度受限制的字符串拷贝,即将 arr 字符串中从前往后取出 2 个字符 "ab",拷贝到 arr1 字符数组空间内。并返回目标空间的起始地址。

模拟实现 strncpy 字符串拷贝函数:

// strncpy 函数模拟实现
char* my_strncpy(char* dest, const char* src, size_t num)
{
	assert(dest && src);                // 断言(检查错误)
	char* ret = dest;                   // 记录下目标空间的起始地址

	while (num)                         // 循环 num 次,即拷贝字符 num 个
	{
		*dest = *src;                   // 源字符串 src指针指向的字符赋给目标空间
		if (*dest == '\0')              // 检测 src赋给dest的字符是否是'\0',是则退出循环
		{
			break;
		}

		++dest;                          // 赋完值后 dest+1,往后移一步
		++src;
		--num;                           // 赋完一次值,num值减一
	}
	while (num)                          // src字符串已全部拷贝到目标空间后,num仍是大于0
	{
		*dest = '\0';                    // dest指针指向的字符之后的内容全部赋值为 '\0'
		++dest;
        --num;                        // 直至num值变为0
	}
	return ret;
}

检查模拟函数是否正确:

模拟成功! 

1.1.2.3:strncat函数

函数简介:

函数介绍:

  • strncat:受长度限制的字符串连接函数
  • " char* strncat(char* destination, const char* source, size_t num)" 
  • 从source字符串从前往后取出 num 个字符连接到destination字符串的后面

函数应用实例:

#include<stdio.h>
#include<string.h>

int main()
{
	// strncat:长度受限制的字符串连接
	// char* strncat(char* dest,const char* src,size_t num)
	char arr[20] = "hello ";
	char arr1[] = "china";
	char* p = strncat(arr, arr1, 2);
	printf("p = %s\n", p);
	printf("arr = %s\n", arr);
    return 0;
}

// 打印结果:
// p = hello ch
// arr = hello ch

分析:长度受限制的字符串连接函数,arr 字符串 "hello ",arr1 字符串 "china"。从 arr1 字符串从前往后取2个字符("ch"),连接到目标空间arr字符串的后面。

注意:目标空间内必须保证有足够的空间来存放所被连接的字符串。

模拟实现 strncat 字符串连接函数:

// 模拟实现 strncat 函数
char* my_strncat(char* dest, const char* src, size_t num)
{
	assert(dest && src);            // 断言(检查是否报错)
	char* ret = dest;               // 将目标空间的起始地址保存
	char* s = src;                  // 通过一个指针来代替src移动
	while (*dest)                   // 找到目标空间的'\0'的位置
	{
		dest++;
	}                                
    // 此时 dest指针指向的内容是'\0'
	while (num)                     // 循环连接 num 次
	{
		*dest = *s;                 // 将指针s的指向的内容赋值给 dest的位置
		if (*s == '\0')             // 检查指针s的指向内容是否为'\0'(结束)
		{
			break;
		}
		++dest;                    // 赋值完之后,dest往后移一位
		++s;                       // 赋值完之后,s往后移一位
		--num;                     // num减一,
	}
	if (num == 0)                   // 当连接 num 个字符后,指针dest指向的位置空间赋值'\0'
	{
		*dest = '\0';
	}
	while (num)                    // 源字符串结束之后,num 值仍大于0,将dest指向位置之后的   num个位置内容都赋值为 '\0'
	{
		*dest = '\0';
		++dest;
	}

	return ret;

}

检查模拟函数是否正确:

 模拟成功!

1.1.2.4:strncmp函数

函数简介:

函数介绍:

strncmp:长度受限制的字符串比较函数

"  int strncmp(const char* str1, const char* str2, size_t num)  " 

通俗来讲:比较num个字符,str1字符串和str2字符串各从前往后取出 num个字符,依次进行相对应的比较。

 函数使用实例:

#include<stdio.h>
#include<string.h>

int main()
{
	// strncmp:长度受限制的字符串比较
	// int strncmp(arr1,arr2,n)
	char a[] = "abcd";
	char b[] = "abcdef";
	int x = strncmp(a, b, 4);
	// a > b  -->  1
	// a = 0  -->  0
	// a < b  -->  -1
	printf("x = %d\n", x);

    return 0;
}

// 打印结果:
// x = 0

分析:a字符数组中取出4个字符为 "abcd",b字符数组中取出4个字符为 "abcd"。"abcd"与"abcd"依次比较对应相等,返回0。

模拟实现 strncmp 字符串比较函数:

// 模拟实现 strncmp 函数
int my_strncmp(const char* str1, const char* str2, size_t num)
{
	assert(str1 && str2);

	while (*str1 == *str2 && num)        // 判断str1和str2指向的内容是否相等,判断num值是否减到0
	{
		++str1;
		++str2;
		--num;
	}
	if (*str1 > *str2)
	{
		return 1;
	}
	else if (*str1 < *str2)
	{
		return -1;
	}
	else
	{
		return 0;
	}

}

检测模拟的函数是否正确:

 模拟成功!

1.2:字符串非常规函数

所谓非常规函数,就是我们在学习的过程中并不需要深度了解它们,只需要学会使用即可,在我们做题时使用该系列函数可以快速地解决问题。

1.2.1:strstr 字符串函数

函数简介:

 函数介绍:

strstr:字符串查找函数

通俗来讲:在字符串中找子字符串(在 str1 字符串中找 str2 字符串,返回 str2 在str1 中第一次出现的位置)

看例题:

#include<stdio.h>
#include<string.h>

int main()
{
	// strstr:字符串中找一个字符串
	// char* strstr(const char* str1,const char* str2)
	// 在 str1 中找 str2,返回 str2 在 str1 中第一次出现的位置	找不到就返回 NULL
	char arr[] = "abcdefabcdef";
	char arr1[] = "def";
	char* ret = strstr(arr, arr1);
	printf("ret = %s\n", ret);
    return 0;

}


// 打印结果:
// ret = defabcdef

分析:arr字符串"abcdefabcdef" ,arr1字符串"def"。在arr字符串内找arr1,即arr字符数组第3个位置可找到,返回一个指向字符 'd' 的地址。

练习:

 提交答案:

#include<stdio.h>
#include<string.h>

int main()
{
    char arr[20] = { 0 };
	char arr1[20] = { 0 };

	gets(arr);
	gets(arr1);

	// 在arr中找arr1
	char* ret1 = strstr(arr, arr1);
	char* ret2 = strstr(arr1, arr);
	if (ret1!=NULL)
	{
		printf("%s is substring of %s\n", arr1, arr);
	}
	else if(ret2!=NULL)
	{
		printf("%s is substring of %s\n", arr, arr1);
	}
	else
	{
		printf("No substring\n");
	}
	return 0;
}

1.2.2:strtok 字符串函数

函数简介:

 函数介绍:

  • char* strtok( char* str, const char* sep)
  • sep参数是个字符串,定义了用作分隔符的字符集合
  • 第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。
  • strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)
  • strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
  • strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
  • 如果字符串中不存在更多的标记,则返回 NULL 指针。

 函数使用样例:

#include<stdio.h>
#include<string.h>

int main()
{
	// strtok:用作分隔符的字符串
	// char * strtok ( char * str, const char * delimiters );
	char arr[] = "china!victory@year.net";
	char cpy[30] = { 0 };
	strcpy(cpy, arr);
	char set[] = "@,.,!";        // 此处的分隔符无顺序讲究
	char* ret = NULL;
	for (ret = strtok(cpy, set); ret != NULL; ret = strtok(NULL, set))
	{
		printf("%s\n", ret);
	}
    return 0;
}


// 打印结果:
// china
// victory
// year
// net

1.2.3:strerror 字符串函数

函数简介:

函数介绍:

主要功能:返回错误码所对应的错误信息。 

 看实例:

#include<stdio.h>
#include<string.h>

int main()
{
	// strerror:错误码所对应的错误信息
	// char* strerror(int errnum)
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d:%s\n", i, strerror(i));
	}
    return 0;
}

// 打印结果:
// 0:No error
// 1:Operation not permitted
// 2:No such file or directory
// 3:No such process
// 4:Interrupted function call
// 5:Input/output error
// 6:No such device or address
// 7:Arg list too long
// 8:Exec format error
// 9:Bad file descriptor

那么,为什么会有这样的错误码和错误原因呢?这是因为C语言中库函数在执行的过程中,发生了错位,会将一个错误码存放在errno(C语言提供的一个全局变量)这个变量中。

二:内存函数

所谓内存函数,即在内存上存储的数据都可以进行相应的操作,不单单是针对于字符,还可以对整形,浮点型,结构体等等进行操作。

2.1:memcpy内存函数

函数简介:

void* memcpy(void* destination, const void* source, size_t num);

 函数介绍:

  • 函数memcpysource的位置开始向后复制num个字节的数据到destination的内存位置。
  • 这个函数在遇到 '\0' 的时候并不会停下来。
  • 如果sourcedestination有任何的重叠,复制的结果都是未定义的
  • 因为是 void* 类型的,所以其函数复制的不仅仅是字符类型的数据,还可以是整形,浮点型等类型的数据。

使用示例:

#include<stdio.h>
#include<string.h>

int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[20] = { 0 };
	memcpy(arr2, arr1, 40);
	int i = 0;
	for (i = 0; i < 20; i++)
	{
		printf("%d ", arr2[i]);
	}
    return 0;
}


// 打印结果:
// 1 2 3 4 5 6 7 8 9 10 0 0 0 0 0 0 0 0 0 0

函数运行前数组arr2数据在内存中情况:

函数运行后数组arr2数据在内存中情况:

分析:因为 num 值针对的是字节,而一个整形占4个字节,所以40个字节就是占的10个数字。所以其拷贝的就是arr1的前10个数字。

再看一例题:

#include<stdio.h>
#include<string.h>

int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[20] = { 0 };
	memcpy(arr2, arr1, 24);
	int i = 0;
	for (i = 0; i < 20; i++)
	{
		printf("%d ", arr2[i]);
	}
    return 0;
}


// 打印结果:
// 1 2 3 4 5 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0

 模拟实现 memcpy 内存拷贝函数:

// 模拟 memcpy内存函数
// void* memcpy(void* destination, const void* source, size_t num);

void* my_memcpy(void* dest, const void* src, size_t num)
{
	assert(dest && src);

	while (num)                        // 循环 num 次(num个字节)
	{
		*(char*)dest = *(char*)src;    // 在未知是什么类型的情况下,要将其类型转成char*类型
		dest = (char*)dest + 1;
		src = (char*)src + 1;
		--num;
	}

}

检测模拟的函数是否正确:

模拟成功! 

2.2:memmove内存函数

函数简介:

void * memmove ( void * destination, const void * source, size_t num );

函数介绍: 

  • memmove函数:内存移动函数。
  • memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
  • 如果源空间和目标空间出现重叠,就得使用memmove函数处理。

使用示例:

#include<stdio.h>
#include<string.h>

int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	memmove(arr1 + 3, arr1, 20);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr1[i]);
	}
    return 0;
}


// 打印结果:
// 1 2 3 1 2 3 4 5 9 10

函数运行前数组arr1数据在内存中情况:

函数运行后数组arr1数据在内存中情况:

分析:

" memmove(arr1 + 3, arr1, 20) "的含义是:在 arr1 数组内取20个字节,因为其类型是整形,所以取出5个整数,将这5个整数放到 arr1+3 这个位置上,将原来的5个数据覆盖掉。

 模拟实现 memmove 内存移动函数:

// 模拟 memmove 内存移动函数
// void * memmove ( void * destination, const void * source, size_t num )
void* my_memmove(void* dest, const void* src, size_t num)
{
	assert(dest && src);

	if (src > dest)
	{

		while (num)
		{
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;

			--num;
		}

	}
	else
	{

		while (num)
		{
			*((char*)dest + num-1) = *((char*)src + num-1);
			--num;
		}
	}
}

 检测模拟的函数是否正确:

模拟成功! 

2.3:memcmp内存函数

函数简介:

int memcmp ( const void * ptr1, const void * ptr2, size_t num );

 函数介绍:

比较从 ptr1 ptr2 指针开始的 num 个字节
返回值如下:

使用示例: 

#include<stdio.h>
#include<string.h>

int main()
{
	int arr1[] = { 1,2,3,4,5 };
	int arr2[] = { 1,2,234,45 };
	int ret = memcmp(arr1, arr2, 9);
	printf("ret = %d\n", ret);
    return 0;
}


// 打印结果:
// x = -1

 注意:这里的 memcmp 比较的并不是依次比较的数字,而是各个字节(9个字节)。因为此函数通常使用率不高,此处不再进行讲解。

2.4:memset内存函数

函数简介:

void * memset ( void * ptr, int value, size_t num );

 函数介绍:

  • 内存设置,填充内存块。
  • 将 ptr 指向的内存块的第一个字节数设置为指定值(val)
  • 通俗来讲:指向 ptr 前 num 个字节设置为 value 值,(以字节为单位设置)

 使用示例:

#include<stdio.h>
#include<string.h>

int main()
{
	char arr[20] = { 0 };
	memset(arr, 'a', 10);
	int i = 0;
	for (i = 0; i < 20; i++)
	{
		printf("%c ", arr[i]);
	}
    return 0;
}


// 打印结果:
// a a a a a a a a a a

函数运行前数组arr数据在内存中情况:

函数运行后数组arr数据在内存中情况:

注意: 此函数一般适用于字符数组

 这里此函数大家可不必深入理解,会用就OK,此处也不再进行讲解。

三:特殊字符函数

不要求深度理解,记得它们会用就OK!

注意:它们所使用的库函数是 <ctype.h>

3.1:字符分类函数

函数
如果他的参数符合下列条件就返回真
isspace
空白字符:空格 ‘ ’ ,换页 ‘\f’ ,换行 '\n' ,回车 ‘\r’ ,制表符 '\t' 或者垂直制表符 '\v'
isdigit
十进制数字 0~9
islower
小写字母 a~z
isupper
大写字母A~Z
isalpha
字母a~z或A~Z
isalnum
字母或者数字,a~z,A~Z,0~9

3.1.1:isspace函数

该函数大部分都是用来检查字符串中是否含有空格。只要有空格就返回真!

使用实例:

#include<stdio.h>
#include<ctype.h>

int main()
{
	char arr[] = "sdsdf123 2fsdvf3 43 sdf";
	int space_count = 0;
	int len = strlen(arr);
	for (int i = 0; i < len; i++)           // 遍历arr字符数组内的各个字符
	{
		if (isspace(arr[i]))                // 遇到空格,计数空格变量就加1
		{
			space_count++;                   
		}
	}
	printf("space_count = %d\n", space_count);

}

// 打印结果:
// 3

3.1.2:isdigit函数

使用该函数,只要遇到十进制数字 0~9就返回真。

使用示例:

#include<stdio.h>
#include<ctype.h>

int main()
{
	char arr[] = "sdsdf123 2fsdvf3 43 sdf";
	int digit_count = 0;
	int len = strlen(arr);
	for (int i = 0; i < len; i++)         // 遍历arr字符数组内的各个字符
	{
		if (isdigit(arr[i]))              // 遇到十进制数字0-9,计数变量就加1
		{
			digit_count++;
		}
	}
	printf("digit_count = %d\n", digit_count);

}


// 运行结果:
// digit_count = 7

3.1.3:islower函数

使用该函数,只要遇到小写字母a~z就返回真。

使用示例:

#include<stdio.h>
#include<ctype.h>

int main()
{
	char arr[] = "sSFdsdSFDf123 2fsdFDvf3 43SF sdf";
	int lower_count = 0;
	int len = strlen(arr);
	for (int i = 0; i < len; i++)         // 遍历arr字符数组内的各个字符
	{
		if (islower(arr[i]))              // 遇到小写字母a~z,计数变量就加1
		{
			lower_count++;
		}
	}
	printf("lower_count = %d\n", lower_count);
    return 0;
}


// 打印结果:
// lower_count = 13

3.1.4:isupper函数

使用该函数,只要遇到大写字母A~Z就返回真。

使用示例:

#include<stdio.h>
#include<ctype.h>

int main()
{
	char arr[] = "sSFdsdSFDf123 2fsdFDvf3 43SF sdf";
	int upper_count = 0;
	int len = strlen(arr);
	for (int i = 0; i < len; i++)         // 遍历arr字符数组内的各个字符
	{
		if (isupper(arr[i]))              // 遇到大写字母A~Z,计数变量就加1
		{
			upper_count++;
		}
	}
	printf("upper_count = %d\n", upper_count);
    return 0;
}


// 打印结果:
// upper_count = 9

3.1.5:isalpha函数

使用该函数,只要遇到字母a~z或A~Z就返回真。

使用示例:

#include<stdio.h>
#include<ctype.h>

int main()
{
	char arr[] = "sSFdsdSFDf123 2fsdFDvf3 43SF sdf";
	int alpha_count = 0;
	int len = strlen(arr);
	for (int i = 0; i < len; i++)         // 遍历arr字符数组内的各个字符
	{
		if (isalpha(arr[i]))              // 遇到字母a~z或A~Z,计数变量就加1
		{
			alpha_count++;
		}
	}
	printf("alpha_count = %d\n", alpha_count);
    return 0;
}


//  打印结果:
// alpha_count = 22

3.1.6:isalnum函数

使用该函数,只要遇到字母或者数字,a~z,A~Z,0~9就返回真。

使用示例:

#include<stdio.h>
#include<ctype.h>

int main()
{
	char arr[] = "sSFdsdSFDf123 2fsdFDvf3 43SF sdf";
	int alnum_count = 0;
	int len = strlen(arr);
	for (int i = 0; i < len; i++)         // 遍历arr字符数组内的各个字符
	{
		if (isalnum(arr[i]))              // 只要遇到字母或者数字,a~z,A~Z,0~9,计数变量就加1
		{
			alnum_count++;
		}
	}
	printf("alnum_count = %d\n", alnum_count);
}


//  打印结果:
// alnum_count = 29

3.2:字符转换函数

3.2.1:tolower函数

功能:将大写字母转变成小写字母。

函数简介:

int tolower ( int c );

为什么传递的是整形?因为字符在内存中存放的是其ASCII码值,即字符也是属于整形的一类。 

使用实例:

#include<stdio.h>
#include<ctype.h>

int main()
{

	// toupper(小写字母-->大写字母)
	// int toupper(int c)

	char arr[] = "AFADFSADFD";
	int len = strlen(arr);
	for (int i = 0; i < len; i++)        // 遍历arr字符数组内的各个字符
	{
		if (isupper(arr[i]))             // 如果有字符是大写字母,就将其转换成小写字母
		{
			arr[i] = tolower(arr[i]);
		}
	}
	printf("%s\n", arr);

}

// 打印结果:
// afadfsadfd



注意:该函数所包含的头文件是 <ctype.h>

3.2.2:toupper函数

功能:将小写字母转变成大写字母。

函数简介:

int toupper ( int c );

使用示例:

#include<stdio.h>
#include<ctype.h>

int main()
{
	// tolower(大写字母-->小写字母)
	// int tolower(int c)            

	char arr[] = "afadfsadfd";
	int len = strlen(arr);
	for (int i = 0; i < len; i++)        // 遍历arr字符数组内的各个字符
	{
		if (islower(arr[i]))             // 如果有字符是小写字母,就将其转换成大写字母
		{
			arr[i] = toupper(arr[i]);
		}
	}
	printf("%s\n", arr);

}

// 打印结果:
// AFADFSADFD

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/699315.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

芯片级激光器研发取得新进展

欢迎关注GZH《光场视觉》 自 20 世纪 60 年代以来&#xff0c;激光给世界带来了革命性的变化&#xff0c;如今已成为从尖端手术和精密制造到光纤数据传输等现代应用中不可或缺的工具。 但是&#xff0c;随着激光应用需求的增长&#xff0c;挑战也随之而来。例如&#xff0c;光…

勒索病毒搜索引擎

360勒索病毒搜索引擎 https://lesuobingdu.360.cn/ 腾讯勒索病毒搜索引擎 https://guanjia.qq.com/pr/ls/ VenusEye勒索病毒搜索引擎 https://lesuo.venuseye.com.cn/ 奇安信勒索病毒搜索引擎 https://lesuobingdu.qianxin.com/index/getFile 深信服勒索病毒搜索引擎…

idea插件开发之hello idea plugin

写在前面 最近一直想研究下自定义idea插件的内容&#xff0c;这样如果是想要什么插件&#xff0c;但又一时找不到合适的&#xff0c;就可以自己来搞啦&#xff01;这不终于有时间来研究下&#xff0c;但过程可谓是一波三折&#xff0c;再一次切身体验了下万事开头难。那么&…

如何用Vue3打造一个逼真的3D手机模型

本文由ScriptEcho平台提供技术支持 项目地址&#xff1a;传送门 手机界面卡片功能实现 应用场景介绍 本代码片段适用于构建移动设备或网页端界面的手机卡片功能。它可以通过简单的HTML、CSS和JavaScript实现一个具有逼真视觉效果和交互功能的手机卡片。 基本功能介绍 该代…

Project 项目管理软件真的好用吗?

作为一个普通的职场人&#xff0c;或许只要掌握office全家桶&#xff0c;即可应对大部分工作。 但对项目经理来说&#xff0c;这是远远不够的。项目经理需要实时掌握项目进度、把关项目质量、应对项目风险、实时分析项目数据&#xff0c;做出正确的决策等等… 而拥有一款高效…

浅谈DALL-E2

目录 1.概述 2.诞生背景 3.作用 4.版本历史 5.模型和技术 6.应用场景 6.1.十个应用场景 6.2.游戏开发 7.接口 8.未来展望 9.总结 1.概述 DALL-E2 是由 OpenAI 开发的一个图像生成模型&#xff0c;可以根据文本描述生成高质量的图像。DALL-E2 是 DALL-E 的升级版&am…

IBM,开始构建以量子为中心的超级计算机

6月6日&#xff0c;IBM与Pasqal宣布了一项重大合作!IBM和Pasqal打算合作开发一种以量子为中心的超级计算的通用方法并促进化学和材料科学的应用研究。IBM和Pasqal将与高性能计算领域的领先机构合作&#xff0c;为以量子为中心的超级计算奠定基础——将量子计算与先进的经典计算…

用于每个平台的最佳WordPress LMS主题

你已选择在 WordPress 上构建学习管理系统 (LMS)了。恭喜&#xff01; 你甚至可能已经选择了要使用的 LMS 插件&#xff0c;这已经是成功的一半了。 现在是时候弄清楚哪个 WordPress LMS 主题要与你的插件配对。 我将解释 LMS 主题和插件之间的区别&#xff0c;以便你了解要…

使用lombok帮我们生成 getter、setter、无参构造器、全参构造器、equals、hashcode

文章目录 为什么要使用lombok&#xff1f;lombok的使用步骤1.检查 idea 是否安装 lombok 插件2.检查是否勾选了 enable annotation processing3.导入 lombok.jar 并加入到模块中4.在实体类添加注解 测试 为什么要使用lombok&#xff1f; lombok可以帮我们生成 getter、setter、…

MySQL-数据处理函数(-1)

033-数据处理函数之获取日期时间 now()&#xff1a;获取的是执行select语句的时刻。sysdate()&#xff1a;获取的是执行sysdate()函数的时刻。 select now(), sleep(2), sysdate();获取当前日期 select curdate(); select current_date(); select current_date;获取当前时间…

超详解——Python 编程中的类型和对象深入探讨——基础篇

目录 1. 内建类型的布尔值 1.1 布尔值的基本规则 1.2 进阶应用 2. 对象身份的比较 2.1 基本概念 2.2 示例代码 2.3 实际应用 3. 对象类型比较 3.1 基本概念 3.2 示例代码 3.3 实际应用 4. 类型工厂函数 4.1 常见的类型工厂函数 4.2 示例代码 4.3 实际应用 5. P…

Docker 安装gitLab

目录 1. 安装 Docker 2. 拉取 GitLab 镜像 3. 创建并运行 GitLab 容器 4. 登录GitLab 修改下载地址 修改账号密码 前言-与正文无关 生活远不止眼前的苦劳与奔波&#xff0c;它还充满了无数值得我们去体验和珍惜的美好事物。在这个快节奏的世界中&#xff0c;我们往往容易…

CISP究竟适合谁?这四类人没跑了

在信息技术飞速发展的现在&#xff0c;网络安全已经成为了一个不可忽视的话题。 CISP&#xff0c;即注册信息安全专业人员&#xff0c;是网络安全领域内一项备受认可的专业认证。 但CISP究竟适合谁考呢&#xff1f;这不仅是一个技术问题&#xff0c;更是一个职业规划的问题。…

fastadmin/thinkPHP5.0的框架使用注意事项

0.主要链接 一张图解析表格 数据表规划一定要做好,省的做的时候很乱,一会要改一下,就特别麻烦 在线命令生成crud的时候一定不要填写自定义控制器名,要让他自己生成,否则后面你要修改东西还需要再找.默认的永远能知道在哪里 在线命令生成的时候,可以试着删除一下(不会成功),但…

Shell脚本和变量

文章目录 Shell脚本shell的解释器Shell的作用Shell脚本的构成Shell的执行方式 重定向操作变量变量的类型&#xff1a;变量名的规范变量值的规范整数运算 &#xff0b; &#xff0d; / %小数运算 小数运算 Shell脚本 脚本就是可运行的代码的集合&#xff0c;脚本语言&#xff…

清华出品,开源最强,我又出手了(全网首发!)

清华出品的ChatGLM-6B自开源那刻起&#xff0c;GLM系列的每一次更新都受到了业界的热切关注。尤其是ChatGLM第3代开源之后&#xff0c;其强大和适配性让很多人惊叹&#xff0c;之后大家对GLM的第4代模型充满了期待。终于&#xff0c;今天它来了&#xff01;我要为大家介绍的是这…

RAG与知识库搭建

Tip: 如果你在进行深度学习、自动驾驶、模型推理、微调或AI绘画出图等任务&#xff0c;并且需要GPU资源&#xff0c;可以考虑使用UCloud云计算旗下的Compshare的GPU算力云平台。他们提供高性价比的4090 GPU&#xff0c;按时收费每卡2.6元&#xff0c;月卡只需要1.7元每小时&…

阿里云百炼开发AI大模型详解

AI项目功能设想描述文档 随着AI发展越来越迅速&#xff0c;各行各业都需考虑如何将AI结合到自己的产品中&#xff0c;目前国内大部分的AI问答网站&#xff0c;都是基于Open AI实现的&#xff0c;但是如何需要运用到企业产品中那我们考虑的因素就会比较多 将ChatGpt移植到企业中…

电流的本质是什么

话说很久以前&#xff0c;科学发现纯靠人眼识别。有一天&#xff0c;泰勒斯(古希腊哲学家&#xff0c;被称为科学的祖师爷)一时手痒&#xff0c;拿着琥珀与皮毛摩擦。 结果他发现那种半透明的小石头&#xff0c;居然产生了吸引小物体的魔力。 面对这个现象&#xff0c;老泰开始…

leetcode-04-[24]两两交换链表中的节点[19]删除链表的倒数第N个节点[160]相交链表[142]环形链表II

一、[24]两两交换链表中的节点 重点&#xff1a;暂存节点 class Solution {public ListNode swapPairs(ListNode head) {ListNode dummyHeadnew ListNode(-1);dummyHead.nexthead;ListNode predummyHead;//重点&#xff1a;存节点while(pre.next!null&&pre.next.next…