C语言字符函数和字符串函数

本文详细介绍了C语言中的字符分类函数(如islower和isupper),字符转换函数(tolower和toupper),以及字符串处理函数如strlen、strcpy、strcmp、strncpy、strcat和strncat的使用方法和示例。展示了如何在C语言中进行字符大小写转换和字符串操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.字符函数

1.1字符分类函数

C语⾔中有⼀系列的函数是专⻔做字符分类的,也就是⼀个字符是属于什么类型的字符的。

这些函数的使⽤都需要包含⼀个头⽂件是 ctype.hicon-default.png?t=N7T8https://legacy.cplusplus.com/reference/cctype/

 594496c5d43242b48852609791d28db3.png

字符分类函数的使用非常相似,我们举其中一例讲解:

int islower ( int c );

该字符函数是用来判断c是否是小写字母,如果是⼩写字⺟就返回⾮0的整数,如果不是⼩写字⺟,则返回 0。 

 写⼀个代码,将⼩写字⺟转⼤写

#include <stdio.h>
#include <ctype.h>
int main()
{
	char a = 0;
	scanf("%c", &a);
	if (islower(a))
	{
		printf("%c\n", a - 32);
	}
	else
	{
		printf("%c\n", a);
	}
	return 0;
}

3af6f792a01f4e5abee76e185f105f0b.png

写⼀个代码,将字符串中的⼩写字⺟转⼤写,其他字符不变。

#include <stdio.h>
#include <ctype.h>
int main()
{
	int i = 0;
	char a[] = "Test String";
	char c = 0;
	while (a[i])
	{
		c = a[i];
		if (islower(c))
		{
			printf("%c", c - 32);
			i++;
		}
		else
		{
			printf("%c", c);
			i++;
		}
	}
	return 0;
}

4038340ca36e4e83b6b5f2179b46d260.png

1.2字符转换函数

C语言中提供了两个字符转换函数:

int tolower ( int c ); //将参数传进去的⼤写字⺟转⼩写  
int toupper ( int c ); //将参数传进去的⼩写字⺟转⼤写 

上⾯的代码,我们将⼩写转⼤写,是通过将其对应的ASCII码-32完成的效果,有了转换函数,就可以直接使⽤ tolower 函 数。 

#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;
}

136f9d758941412bb37348446dfa8eb1.png

2.字符串函数

2.1表示字符串和字符串I/O

2.1.1如何定义字符串

如果字符串常量之间没有间隔,或者用空白字符分隔,C默认将其是为串连起来的字符串常量

//两行代码等价
char str[] = "we, are"" are" " the""best!";
char str[] = "we,are the best!"

如果想在内部使用双引号,则在双引号面加一个反斜杠\

char str[] = "\"we are the best!\"Jack says"

492e584a2a92407baeccb4017d81c4cf.png

字符串常量属于静态存储类型,这说明如果在函数中使用字符串常量,该字符串只会被存储一次,在整个程序的生命周期内存在,即使函数被调用多次。用双引号括起来的内容被视为指向该字符串的指针。类似于数组名作为指向该数组位置的指针。

int main()
{
	printf("%s, %p, %c\n", "we", "are", *"the best");
	return 0;
}

9de7f637839e4ecd96e5eb4ed29349d8.png

2.1.2字符串数组和初始化

char str[10] = {'t','h','e',' ','b','e','s','t','\0'};

注意:最后的空字符('\0'),如果没有这个空字符,这就不是一个字符串,而是一个字符数组。

           在指定数组大小时,要确定数组的元素个数至少比字符串长度多1(目的是为了容纳空字符)。对于未被使用的元素都会被自动初始化为0(char形式的空字符)

54806b0eafaa44388cdbc77a4351c5a0.png

2.1.3数组和指针

通常,字符串都作为可执行文件的一部分存储在数据段中,当把程序载入内存时也载入程序中的字符串,字符串存储在静态内存区,但是程序在运行时才会为该数组分配内存。此时才将字符串拷贝到数组中。

此时,字符串有两个副本。一个是在静态内存中的字符串常量,另一个是存储在数组中的字符串。

在数组形式中,数组名是地址常量,这意味着不能更改,不能进行++arr之类的操作但可以进行整体+1的操作 

而对于指针形式(*ptr),在程序执行时就会为指针变量留出一个存储位置,并把字符串的地址存储在指针变量中,该变量最初指向该字符串的首字符,但值可以改变,并且可以使用递增运算符,(++ptr)则表示指向第二个字符

总结:初始化数组把静态存储区的字符串拷贝给一个数组中,而初始化指针只把字符串的地址拷贝给指针

int main()
{
	char a[] = "abc";
	const char* p = "abc";
	printf("abc的地址:%p\n", "abc");
	printf("数组名a的地址:%p\n", a);
	printf("指针p的地址:%p\n", p);

	printf("abc的地址:%p\n", "abc");


	return 0;
}

e14f203de5e04489a579e2fec471cf83.png

该程序说明了:

1.数组名a的地址和指针p的地址不同,这验证了以上总结的内容

2.多次使用printf()函数打印字符串常量地址均一样,但是编译器只使用了一个存储位置,而且与指针p的地址一样,因为它们都表示字符串地址。编译器可以把多次使用的相同字面量存储在一处或多处,这取决于编译器

3.静态数据使用(字符串abc)的内存  与  a数组动态数据使用的内存不同

2.1.4数组和指针的区别

两者的主要区别:数组名是常量,指针名是变量

当我们打算修改字符串时,要用数组的形式来修改,尽量不要用指针

如若用指针要使用const限定符,const修饰指针变量应如何使用:https://blog.youkuaiyun.com/weixin_61196535/article/details/135091722?spm=1001.2014.3001.5501

#include <stdio.h>  
#include <string.h>  
  
int main() {  
    // 创建一个字符数组,用于存储字符串  
    char str[100] = "Hello, World!";  
  
    // 输出原始字符串  
    printf("原始字符串: %s\n", str);  
  
    // 修改字符串中的某个字符  
    // 在这个例子中,我们将 'o' 修改为 'X'  
    for (int i = 0; i < strlen(str); i++) {  
        if (str[i] == 'o') {  
            str[i] = 'X';  
        }  
    }  
  
    // 输出修改后的字符串  
    printf("修改后的字符串: %s\n", str);  
  
    return 0;  
}

 2.2字符串函数

2.2.1strlen函数的使用和模拟实现

strlenicon-default.png?t=N7T8https://legacy.cplusplus.com/reference/cstring/strlen/?kw=strlen

size_t strlen ( const char * str );

•字符串以 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前⾯出现的字符个数(不包含 '\0' )。 

• 参数指向的字符串必须要以 '\0' 结束。

• 注意函数的返回值为size_t,是⽆符号的( 易错 )

• strlen的使⽤需要包含头⽂件

模拟实现:

方式一:通过计数器的方式实现,使用循环将字符挨个传递,用count计数并返回

//计数器⽅式 
int my_strlen(const char* str)
{
	int count = 0;
	assert(str);
	while (*str)
	{
		count++;
		str++;
	}
	return count;
}

方式二: 字符串首指针-尾指针,指针相减得到的是元素个数

//指针-指针的⽅式 
int my_strlen(char* s)
{
	assert(str);
	char* p = s;
	while (*p != ‘\0’)
		p++;
	return p - s;
}

方式三:递归,要求不能创建了临时变量

int my_strlen(const char* str)
{
	assert(str);
	if (*str == '\0')
		return 0;
	else
		return 1 + my_strlen(str + 1);
}

2.2.2strcpy的使⽤和模拟实现

strcpy是字符串复制函数。

strcpyicon-default.png?t=N7T8https://legacy.cplusplus.com/reference/cstring/strcpy/?kw=strcpy

char* strcpy(char * destination, const char * source );

6aadb55388344914bc6b722156517e64.png

空字符串也拷贝

• 源字符串必须以 '\0' 结束。

• 会将源字符串中的 '\0' 拷⻉到⽬标空间。

• ⽬标空间必须⾜够⼤,以确保能存放源字符串。

• ⽬标空间必须可修改。  

使用:

#include<stdio.h>
#include<string.h>
 
int main()
{
	char arr1[10] = { "home" };
	char arr2[5] = { "ouse" };
	strcpy(arr1+1, arr2);
	printf("%s", arr1);
 
	return 0;
}

模拟: 

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

	while ((*dest++ = *src++))
	{
		;
	}
	return ret;
}

 更加巧妙的写法:

6b80e422178340d89c4f5372ef2c434c.png  

2.2.3strcmp的使⽤和模拟实现

strcmpicon-default.png?t=N7T8https://legacy.cplusplus.com/reference/cstring/strcmp/?kw=strcmp

标准规定:

◦ 第⼀个字符串⼤于第⼆个字符串,则返回⼤于0的数字

◦ 第⼀个字符串等于第⼆个字符串,则返回0

◦ 第⼀个字符串⼩于第⼆个字符串,则返回⼩于0的数字

◦ 那么如何判断两个字符串? ⽐较两个字符串中对应位置上字符ASCII码值的⼤⼩。

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

2.2.4strncmp函数的使⽤

char * strncpy ( char * destination, const char * source, size_t num );
//(目标空间,源字符串,复制个数)

拷贝num个字符串到目标空间。

如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。

2.2.5strcat函数的使⽤ 

//strcat是字符串追加函数

char * strcat ( char * destination, const char * source );(目标空间,源字符串)

源字符串必须以'\0'结束。

目标空间必须足够大能够存放源字符串。

目标必须可变。

strcat不能自己给自己追加。(会将自己的'\0'覆盖)

#include<stdio.h>
#include<string.h>
 
int main()
{
	char arr1[20] = { "hello " };
	char arr2[10] = { "world" };
	strcat(arr1, arr2);
	printf("%s", arr1);
 
    strcat(arr2,arr2)//错误
 
	return 0;
}

2.2.6strncat函数的使用

char * strncat ( char * destination, const char * source, size_t num );(目标空间,源字符串,追加个数)

追加num个字符串到目标空间,外加一个'\0'。

如果中 C 字符串的长度小于 num,则仅复制'\0'之前的内容。

#include<stdio.h>
#include<string.h>
 
int main()
{
	char arr1[10] = { "ha" };
	char arr2[5] = { "hahe" };
	strncat(arr1, arr2, 2);
	printf("%s", arr1);
 
	return 0;
}

 ba68f43c05784645aaad12b84a6e6917.png

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值