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

news2024/12/25 0:29:17

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

目录

思维导图:

一:字符串函数

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

工业镜头孔径、分辨率与景深参数简析

工业镜头孔径、分辨率与景深参数简析 一、前言二、镜头孔径与光圈系数2.1孔径与相对孔径2.2数值孔径&#xff08;NA&#xff09;2.3光圈系数&#xff08;F/#&#xff09;2.4工作光圈系数&#xff08;&#xff08;F/#&#xff09;w&#xff09; 三、镜头分辨率3.1MTF与CTF3.1.1M…

干货分享!2024年Instagram营销必备插件

Instagram是营销人员常用的社交媒体平台&#xff0c;通过提升品牌知名度来推动业务增长。今天给大家分享一些超实用的Instagram营销插件&#xff0c;无论是下载图片视频&#xff0c;还是预先发布帖子&#xff0c;这些工具都可以是你的得力助手&#xff0c;让你的INS运营效率蹭蹭…

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

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

Activiti7 Maven笔记

通过maven完成BPMN的创建,定义流程,部署流程,完成流程等操作 代码整合创建maven项目添加log4j日志配置添加activiti配置文件创建数据库 activitijava类编写程序生成表如果代码运行,没有生成表,可能是没有读取到activiti的配置文件 Activiti数据表介绍类关系图工作流引擎创建默认…

AI产品经理的转行之路,如何迈向年薪80w的职业高峰?

前言 在当今科技日新月异的时代&#xff0c;AI产品经理作为一个炙手可热的职业&#xff0c;吸引了众多向往高薪与前沿领域结合的求职者的目光。年薪80万的诱惑力无疑是巨大的&#xff0c;但不少自学中的朋友发现&#xff0c;即便涉猎广泛的产品知识&#xff0c;想要顺利转型成…

力扣 42. 接雨水

题目来源&#xff1a;https://leetcode.cn/problems/trapping-rain-water/description/ C题解1&#xff1a;双指针 按列算&#xff0c;一列一列的求雨水面积。使用双指针是记录当前列左右侧的最大元素。 class Solution { public:int trap(vector<int>& height) {in…

中电联系列三:rocket手把手教你理解中电联协议!

分享《慧哥的充电桩开源SAAS系统&#xff0c;支持汽车充电桩、二轮自行车充电桩。》 前 言 T/CEC102《电动汽车充换电服务信息交换》共分为四个部分&#xff1a; ——第1部分&#xff1a;总则&#xff1b; ——第2部分&#xff1a;公共信息交换规范&#xff1b; ——第3部分&a…

【ARM Cache 及 MMU 系列文章 1.3 -- 如何判断 L2 Cache 是否实现】

请阅读【ARM Cache 及 MMU/MPU 系列文章专栏导读】 及【嵌入式开发学习必备专栏】 文章目录 CPU Configuration Register代码实现CPU Configuration Register 在 armv9 架构中,我们可以通过arm 提供的自定义寄存器IMP_CPUCFR_EL1 来判断当前系统中是否实现了 L2 Cache, 如下所…

【Linux系统编程】进程终止

目录 strerror函数 errno错误码 退出码 正常终止&#xff08;可以通过 echo $? 查看进程退出码&#xff09;&#xff1a; 1. 从main返回&#xff08;return&#xff09; 2. 调用exit 3. _exit&#xff08;一般尽量不要用&#xff09; 异常退出&#xff1a; ctrl c&am…

django 旅游服务系统-计算机毕业设计源码88939

摘 要 旅游服务系统采用采用django框架、python语言、以及Mysql数据库等技术。系统主要分为管理员和用户两部分&#xff0c;管理员管理主要功能包括&#xff1a;首页、轮播图&#xff08;轮播图管理&#xff09;、公告信息管理&#xff08;公告信息&#xff09;、资源管理&…

解析 Spring 框架中的三种 BeanName 生成策略

在 Spring 框架中&#xff0c;定义 Bean 时不一定需要指定名称&#xff0c;Spring 会智能生成默认名称。本文将介绍 Spring 的三种 BeanName 生成器&#xff0c;包括在 XML 配置、Java 注解和组件扫描中使用的情况&#xff0c;并解释它们如何自动创建和管理 Bean 名称。 1. Be…

2024 年 5 月区块链游戏研报:市值增长、玩家参与变迁、迷你游戏兴起

作者&#xff1a;stellafootprint.network 数据来源&#xff1a;GameFi 研究页面 2024 年 5 月&#xff0c;以太坊的表现因 SEC 批准现货以太坊 ETF 的初步申请而得到显著提振。区块链游戏代币的总市值达到 201 亿美元&#xff0c;环比上涨 6.7%。然而&#xff0c;尽管市值有…

年薪80w的AI产品经理技术知识合集

前言 最近&#xff0c;有很多的小伙伴向我咨询&#xff0c;为什么他们学习了大量的产品相关知识&#xff0c;却依然难以转行成为AI产品经理。经过分析&#xff0c;我发现主要原因可以归结为三点&#xff1a;不系统、没产出、不懂技术。那么&#xff0c;如何才能突破这些障碍&a…

ES升级--05--快照生成 和备份

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 备份ES数据1.关闭集群自动均衡2.执行同步刷新3.停止集群节点的Elasticsearch服务4.修改Elasticsearch配置文件&#xff0c;开启快照功能&#xff0c;配置仓库目录为…

金融数据中心布线运维管理解决方案

金融行业的核心业务&#xff0c;如交易、支付、结算等&#xff0c;对网络的依赖程度极高。布线作为网络基础设施的重要组成部分&#xff0c;其稳定性和可靠性直接关系到业务的连续运行。因此&#xff0c;良好的布线管理能够确保网络系统的稳定运行&#xff0c;减少因网络故障导…

EVS9329-ES驱动器EVS9329ES可议价

EVS9329-ES驱动器EVS9329ES可议价 EVS9329-ES驱动器EVS9329ES可议价 EVS9329-ES驱动器EVS9329ES可议价 EVS9329-ES驱动器EVS9329ES可议价 EVS9329-ES驱动器EVS9329ES可议价 EVS9329-ES步进电机按结构分类&#xff1a;步进电动机也叫脉冲电机&#xff0c;包括反应式步进电动…

VBA即用型代码手册:删除空列Delete Empty Columns

我给VBA下的定义&#xff1a;VBA是个人小型自动化处理的有效工具。可以大大提高自己的劳动效率&#xff0c;而且可以提高数据的准确性。我这里专注VBA,将我多年的经验汇集在VBA系列九套教程中。 作为我的学员要利用我的积木编程思想&#xff0c;积木编程最重要的是积木如何搭建…

Transformer结合U-Net登上Nature子刊!最新成果让精度和效率都很美丽

最近一种基于视觉Transformer改进的U-Net来检测多光谱卫星图像中甲烷排放的深度学习方法登上了Nature子刊。与传统方法相比&#xff0c;该方法可以识别更小的甲烷羽流&#xff0c;显著提高检测能力。 这类Transformer与U-Net结合的策略是一种创新的深度学习方法&#xff0c;它…

账号密码无错误,xshell可以连接,但是WindTerm连接失败

xshell可以连接&#xff0c;但是WindTerm却连接失败 报错提示内容&#xff1a; 连接WindTerm是&#xff0c;账号密码是正确的&#xff0c;但是一输入账号&#xff0c;就报The remote host closed the connection错误&#xff0c;或者是Unknown error错误 解决方法 在新建…

数据可视化如何提升智慧展厅的展示效果

数据可视化是如何在智慧展厅中发挥作用的&#xff1f;随着科技的进步&#xff0c;智慧展厅成为展示信息、互动体验和传递品牌价值的前沿平台。数据可视化作为智慧展厅的重要组成部分&#xff0c;通过将复杂的数据转化为直观的图形、图表和互动界面&#xff0c;极大地提升了展厅…