字符函数和字符串函数

  • 一、前言
  • 二、字符函数
    • 2、字符分类函数
      • 2.1 字符函数的形式,与上面表格其他函数通用
      • 2.2 示例1
      • 2.3 示例2
      • 2.4 用islower将小写字母改为大写字母
        • 1>无字符函数
        • 2>字符函数
    • 3、字符转换函数
      • 3.1**toupper函数(小写转大写)的使用**
      • 3.2islower、isupper、tolower、toupper混合使用
    • 4、字符函数总结
  • 三、字符串函数
    • 5、strlen计算字符串长度的使用
      • 5.1 语法形式·注意事项
      • 5.2 模拟实现
        • 1>使用计数器
        • 2>双指针
        • 3>递归函数
    • 6、strcpy拷贝字符串的使用
      • 6.1 语法形式·注意事项
      • 6.2 strcpy的使用
      • 6.3 strcpy函数的模拟实现
      • 6.4 注意事项
    • 7、strcat追加字符串的使用
      • 7.1 语法形式·注意事项
      • 7.2 strcat函数的使用
      • 7.3 strcat函数的模拟实现
        • 示意图:
        • 代码实现:
      • 7.4 字符串追加自己(错误示范)
    • 8、strcmp比较字符串的使用
      • 8.1 语法形式:
      • 8.2 比较两字符串的错误示范
        • (错误示范1)
        • (错误示范2)
      • 8.3 strcmp函数的使用
      • 8.4 strcmp函数的模拟实现
        • 运行图:
        • 代码实现
    • 9、strncpy使用
      • 9.1 语法形式·注意事项
      • 9.2 示例
    • 10、strncat函数的使用
      • 10.1 语法形式·注意事项
      • 10.2 示例
    • 11、strncmp函数的使用
      • 11.1 语法形式·注意事项
      • 11.2 示例
    • 12、strstr函数的使用和实现
      • 12.1 语法形式·注意事项
      • 12.2 strstr函数使用
      • 12.3 模拟strstr函数实现
        • 代码分析图示:
        • 代码实现:
    • 13、strtok函数的使用和实现
      • 13.1 语法形式和注意事项
      • 13.2 strtok函数的使用
    • 14、 strerror函数的使用
      • 14.1 语法形式和注意事项
      • 14.2 示例
      • 14.3 perror函数
      • 14.4 语法形式和注意事项
      • 14.5 示例

一、前言


在C语言的基础库函数中,字符函数是处理单个字符的“微型工具集”,有着以下的优点:

  • 判断一个字符是否为字母、数字,还是大小写的互相转换,都以简洁的形式封装了底层ASCLL码逻辑
  • 命令行输入的合法性检验
  • 字符串处理中对特定字符的筛选
  • 数据格式化输出的大小写调整

以上功能不仅简化了代码的编写,更规避了因直接操作ASCLL码可能导致的逻辑漏洞,时构建字符串逻辑的基础。本文将围绕常用字符函数的功能、实现原理及典型应用场景展开,带你吃透这些“小而美”的工具背后的设计逻辑与实用价值。

二、字符函数


我们经常会处理字符和字符串,所以在C语言中,有一系列函数是专门做字符分类的,如字符分类函数。

2、字符分类函数


顾名思义,字符分类函数是用来分类是否是小写字母or大写字母or空白字符等等,用俗话说你是什么类型的。所以在下列表格中,以下函数都有不同的筛选作用,想要实现这些函数的使用,都需要包含一个头文件ctype.h

函数参数符合条件返回真
iscntrl任何控制字符
isspace空白字符:如空格、换行’\n’,回车等等(在键盘中敲下的字符看不见)
isdigit判断十进制数字0~9字符
isxdigit判断十六进制数字,包括所有十进制数字字符,小写字母,大写字母
islower判断小写字母
isupper判断大写字母
isalpha判断小写+大写字母
isalnum判断字母或数字
ispunct判断标点符号,任何不属于
isgraph判断图形字符
isprint判断可打印字符,包括图形字符和空白字符

以上函数的用法十分相似,这里就举islower和isupper的例子:

2.1 字符函数的形式,与上面表格其他函数通用

int islower (int c);// 把字符的ASCLL码值传到int c中
//如果是小写字符返回非0值(真),如果是其他字符返回0(假)

2.2 示例1


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

int main()
{
	int ret = islower('a');
	printf("%d\n", ret);//2

	return 0;
}

代码输出如下图所示:

因为islower判断是小写字母,返回是非0,可知输出结果为2(非0),其他函数用法也一样。

2.3 示例2


判断是否为空白字符,用isspace检查

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

int main()
{
	int ret = isspace(' ');
	printf("%d\n", ret);//8

	return 0;
}

输出的结果为非零值

8

2.4 用islower将小写字母改为大写字母


头文件***ctype.h***

我将用原始方法和字符函数的方法进行比较。

1>无字符函数
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<ctype.h>

int main()
{
	int i = 0;
	char arr[] = "Hallo World";
	while (arr[i] != '\0')
	{
		if (arr[i] >= 'a' && arr[i] <= 'z')//判断是否是小写字母,若成立则把ASCLL码值减32
		{
			arr[i] -= 32;
		}
		i++;
	}
	printf("%s\n", arr);
	return 0;
}

输出的结果为:

2>字符函数
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<ctype.h>

int main()
{
	int i = 0;
	char arr[] = "Hallo World";
	while (arr[i] != '\0')
	{
		if (islower(arr[i]))//判断是否是小写字母,若成立则把ASCLL码值减32
		{
			arr[i] -= 32;
		}
		i++;
	}
	printf("%s\n", arr);
	return 0;
}

打印的结果相同。

总结:islower(arr[i]) = arr[i] >= 'a' && arr[i] <= 'z'

3、字符转换函数


头文件***ctype.h***

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

int tolower (int c);//将参数传进去的大写字母转成小写字母
int toupper (int c);//将参数传进去的小写字母转成大写字母(相反)

拆解下意思:

  • to(走向) + lower(下方的) --> 下方的字符就是小写字母,所以tolower就是转为小写字母
  • to(走向) + upper(上面的) --> 上面的字符就是大写字母,所以toupper就是转为大写字母

上面的代码,我们将小写转大写,是-32完成的效果,有了转换函数,就可以直接使用tolower函数,下面是toupper函数(小写转大写)的使用

3.1toupper函数(小写转大写)的使用

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

int main()
{
	printf("%c\n", toupper('a'));
	printf("%c\n", toupper('B'));

	return 0;
}

输出结果如下:

函数tolower就不必多说了,就是把A–>a

3.2islower、isupper、tolower、toupper混合使用


还是上面代码的例子(小写转为大写):头文件***ctype.h***

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

int main()
{
	int i = 0;
	char arr[] = "Hallo World";
	while (arr[i] != '\0')
	{
		if (islower(arr[i]))//判断是否是小写字母,少了两次调用,更推荐
		{
			arr[i] = toupper(arr[i]);//arr[i] -= 32;
		}
		i++;
	}
	printf("%s\n", arr);//HALLO WORLD
	return 0;
}

相反把大写改成小写则是

islower-->isupper;   toupper-->tolower;

4、字符函数总结


回顾下下列表格,是不是其他的也会用啦!
注意包含头文件***ctype.h***。

iscntrl任何控制字符
isspace空白字符:如空格、换行’\n’,回车等等(在键盘中敲下的字符看不见)
isdigit判断十进制数字0~9字符
isxdigit判断十六进制数字,包括所有十进制数字字符,小写字母,大写字母
islower判断小写字母
isupper判断大写字母
isalpha判断小写+大写字母
isalnum判断字母或数字
ispunct判断标点符号,任何不属于
isgraph判断图形字符
isprint判断可打印字符,包括图形字符和空白字符
islowerisuppertolowertoupper
锁定小写锁定大写A–>aa–>A

三、字符串函数


5、strlen计算字符串长度的使用

5.1 语法形式·注意事项

size_t strlen (const char * str);
  • 求的是字符串的长度,统计的是字符串中\0之前的字符个数,不包括\0/(字符串中必须有\0,不然就会一直往后找,直到找到为止)
  • 返回值为size_t(无符号类型),不会打印负数
printf("%zu",strlen("abc") - strlen("abcdef"))//3
printf("%zu",(int)strlen("abc") - ((int)strlen("abcdef"))//需转化为int类型,才能打印-3
  • strlen的使用包含头文件***string.h***

5.2 模拟实现


1>使用计数器

思路:通过指针指向数组首地址,向右找到字符串末尾的\0,每走一次计数器+1

实现:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<assert.h>//断言头文件

size_t my_strlen(const char* arr)
{
	assert(arr);//断言,若不是数组就报错
	int count = 0;//计数器
	while (*arr != '\0')
	{
		count++;
		arr++;
	}
	return count;
}

int main()
{
	char arr[] = "abcdef";
	size_t len = my_strlen(arr);
	printf("%zd\n", len);//打印出len=6

	return 0;
}

2>双指针

思路:先设定一个首元素地址,再利用末元素地址,然后相减

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<assert.h>//断言头文件

size_t my_strlen(const char* arr)
{
	assert(arr);//如果不是数组,就报错
	char* p = arr;//首元素
	char* ps = arr;//设个首元素,往下找到\0的地址
	while (*ps != '\0')
	{
		ps++;
	}
	return ps - p;//相减,得到中间元素
}

int main()
{
	char arr[] = "hallo world";
	size_t len = my_strlen(arr);
	printf("%zu\n", len);
	return 0;
}
3>递归函数

思路:由复杂到简单的思想

 把hallo world拆成1 + allo world
 继续拆成1 + 1 + llo world。一直循环到只有\0停下
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>

size_t my_strlen(const char* arr)
{
	if (*arr != '\0')
	{
		return 1 + my_strlen(arr + 1);//当不为\0时,让数组地址往下一个加个整形,回到函数
	}
	else
		return 0;
}

int main()
{
	char arr[] = "hallo world";
	size_t len = my_strlen(arr);
	printf("%zu\n", len);
	return 0;
}

6、strcpy拷贝字符串的使用


头文件:string.h

6.1 语法形式·注意事项

//把source(源头)字符串拷贝给destination(目的地)
char * strcpy (char * destination, const char * source);
  • 源字符串必须以’\0’结束
  • 会将源字符串中的’\0’拷贝到目标空间
  • 目标空间必须足够大,以确保存放源字符串
  • 目标空间必须是可修改的
char* p = "hallo world"//这是常量字符串,不可被修改

6.2 strcpy的使用


int main()
{
	char arr1[] = "hello world";
	char arr2[20] = {0};//目标空间必须要放得下源头字符串
	strcpy(arr2, arr1);
	printf("arr2 = %s\n",arr2);
	return 0;
}

打印出的结果为:

arr2 = hallo world

6.3 strcpy函数的模拟实现


#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<assert.h>

void my_strcpy(char* arr1, char* arr2)
{
	assert(arr1 != NULL);
	assert(arr2 != NULL);
	//拷贝'\0'之前的字符
	while (*arr1 != '\0')
	{
		*arr2 = *arr1;
		arr2++;//可改成*arr2++ = *arr1++;
		arr1++;
	}
	//拷贝'\0'字符
	*arr2 = *arr1;
}

int main()
{
	char arr1[] = "hallo world";
	char arr2[20] = { 0 };

	my_strcpy(arr1, arr2);

	printf("%s\n", arr2);
	return 0;
}

6.4 注意事项


把arr2初始化为"xxxxxxxxxxxxxxxxxxx";观察除了字符,\0是否被复制下来。
如下图所示:



[11]由’x’----->’\0’,’\0’也连同被拷贝。

7、strcat追加字符串的使用


7.1 语法形式·注意事项


str家族的形式都一致,与strcpy的形式一样,只需记住一个即可

//把source(源头)字符串拷贝给destination(目的地)
char * strcpy (char * destination, const char * source);//加const,防止源字符串被窜写
  • 目标字符串中也得有\0,否则没办法知道追加从哪开始
  • 目标空间必须足够大,能容下源字符串的内容
  • 目标内容必须可修改
  • 字符串自己给自己追加

7.2 strcat函数的使用


#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
int main()
{
	char arr1[20] = "hallo ";//追加空间要足够大
	char arr2[] = "world";

	strcat(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

7.3 strcat函数的模拟实现


示意图:

代码实现:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<assert.h>

//返回值为char*,接收类型也为char*
char* my_strcat(char* dest, const char* src)//const保护源数据,防止被修改
{
	//断言,若不是字符指针,则报错
	assert(dest && src);
	//保存dest首地址
	char* ret = dest;
	//1.找目标空间\0
	while (*dest != '\0')
		dest++;
	//2.拷贝到dest\0的后面,打印为halloworld\0
	while (*dest++ = *src++)
		;//空语句
	return ret;//函数的返回值为数组首元素,这样数组才能往下打印完全
}
int main()
{
	char arr1[20] = "hallo ";//追加空间要足够大
	char arr2[] = "world";

	char* s = my_strcat(arr1, arr2);//接收类型为char*
	printf("%s\n", arr1);
	printf("%s\n", s);
	printf("%s\n", my_strcat(arr1, arr2));//arr1已经为hallo world再与arr2进行合并,变为hallo worldworld

	return 0;
}

上面不同字符串追加成功了,那能不能追加自己

7.4 字符串追加自己(错误示范)


理论如下图所示:

字符串追加自己的方法是不可行的。

8、strcmp比较字符串的使用


8.1 语法形式:


//两边加const,防止字符串把修改
int strcmp(const char * str1, const char * str2);
//当str1 > str2返回1
//当str1 = str2返回0
//当str1 < str2返回-1
  • 当str1 > str2返回1
  • 当str1 = str2返回0
  • 当str1 < str2返回-1
  • 头文件***string.h***
  • 第⼀个字符串⼤于第⼆个字符串,则返回⼤于0的数字
  • 第⼀个字符串等于第⼆个字符串,则返回0
  • 第⼀个字符串⼩于第⼆个字符串,则返回⼩于0的数字

8.2 比较两字符串的错误示范


(错误示范1)
char arr1[] = "abcdef";
char arr2[] = "abcdef";
if(arr1 == arr2)//err:比较的是首元素地址
{
}
(错误示范2)
char* p = "abcdef";
if("abcdef" == "abc")//err:比较的是首元素地址
{
}

那么如何判断两个字符串? 比较两个字符串中对应位置上字符ASCII码值的大小

8.3 strcmp函数的使用

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>//strcmp头文件
#include<assert.h>//断言头文件

int my_strcmp(const char* arr1, const char* arr2)
{
	assert(arr1 && arr2);
	int s = strcmp(arr1, arr2);//将返回值传到s中
	return s;//返回值s = 0;
}

int main()
{
	char arr1[] = "hallo";
	char arr2[] = "hallo";//arr1 == arr2
	int set = my_strcmp(arr1, arr2);
	printf("%d\n", set);//set = 0;说明两个字符串是相同的
	return 0;
}

8.4 strcmp函数的模拟实现

运行图:

代码实现
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<assert.h>断言头文件

int my_strcmp(char* arr1, char* arr2)
{
	assert(arr1 && arr2);//判断是否为空指针
	while (*arr1 == *arr2)
	{
		if (*arr1 == '\0')//当最后都相等时,返回0
			return 0;
		arr1++;//如上面图所示
		arr2++;
	}

	if (*arr1 > *arr2)//当大于时,返回1
		return 1;
	if (*arr1 < *arr2)//当小于时,返回-1
		return -1;
}

int main()
{
	char arr1[] = "hallo";
	char arr2[] = "hallo";//两字符串相等,应返回0
	int set = my_strcmp(arr1, arr2);
	printf("%d\n", set);//set = 0
	return 0;
}

9、strncpy使用


9.1 语法形式·注意事项


1 char * strncpy ( char * destination, const char * source, size_t num );
  • 拷贝num个字符从源字符串到目标空间
  • 如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个
  • 其他与[[字符函数#6.1 形式|strcpy的形式]]一致

9.2 示例

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

int main()
{
	char arr1[20] = "xxxx";
	char arr2[] = "yy\0yyy";
	strncpy(arr1, arr2, 4);
	printf("%s\n", arr1);
	return 0;
}

输出结果为:

yy

当拷贝前4个yy\0y字符时,\0会被拷贝进去,导致后面的y被截下。

如果把\0去掉,则结果为:

yyyy

10、strncat函数的使用


10.1 语法形式·注意事项

char * strncat ( char * destination, const char * source, size_t num );
  • 将source指向字符串的前num个字符追加到destination指向的字符串末尾,再追加⼀个 \0 字符
  • 如果source 指向的字符串的⻓度小于num的时候,只会将字符串中到\0 的内容追加到destination指向的字符串末尾

10.2 示例


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

int main()
{
	char arr1[20] = "abcdef";
	char arr2[20] = "yy\0yyy";
	strncat(arr2, arr1, 5);
	printf("%s\n", arr1);//yyabcde
	return 0;
}

监控如下:

效果与上面一致:

  • 将source指向字符串的前num个字符追加到destination指向的字符串末尾,再追加⼀个 \0 字符
  • 如果source 指向的字符串的⻓度小于num的时候,只会将字符串中到\0 的内容追加到destination指向的字符串末尾

11、strncmp函数的使用


11.1 语法形式·注意事项

int a = strcmp(char * destination, const char * source, size_t num)
  • 比较str1和str2的前num个字符,如果相等就继续往后比较,最多比较num个字⺟,如果提前发现不⼀样,就提前结束,大的字符所在的字符串大于另外⼀个。如果num个字符都相等,就是相等返回0

11.2 示例

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

int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "abclef";
	int a = strncmp(arr2, arr1, 3);
	printf("%d\n", a);//a=0;
	return 0;
}
  • 当把3改成4时,是拿前4个字符比较。在第四个字符中arr1中的d小于arr2中的l,返回-1

12、strstr函数的使用和实现


12.1 语法形式·注意事项


char * strstr ( const char * str1, const char * str2);
  • 函数返回字符串str2在字符串str1中第⼀次出现的位置
  • 字符串的比较匹配不包含\0字符,以\0作为结束标志

12.2 strstr函数使用


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

int main()
{
	char arr1[] = "this is apple";
	char arr2[] = "is";
	char* ret = strstr(arr1, arr2);
	
	if (ret != NULL)
	printf("%s\n", ret);
	else
		printf("没找到\n");
	return 0;
}

打印结果如下:

is is apple

12.3 模拟strstr函数实现


代码分析图示:

代码实现:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>//strstr头文件

char* my_strstr(char* str1, char* str2)
{
	const char* s1 = NULL;
	const char* s2 = NULL;//将s1与s2设为空指针
	const char* cur = str1;//设个cur指针指向首地址,方便回到上次查找str1的地方

	if (*str2 == '\0')//极端情况,str2没有字符
	{
		return (char*)str1;//则直接返回str1的首地址
	}

	while (*cur)//当*cur为'\0'退出循环,'\0'的ASCLL码值为0
	{
		s1 = cur;
		s2 = str2;//把s1、s2附上首元素地址

		while (*s1 != '\0' && *s2 != '0' && *s1 == *s2)
		{
			s1++;
			s2++;//查找两元素是否相同
			return (char*)cur;//查找到最后都相同时,返回
		}
		cur++;//条件不成立时,使cur向--→移一位,继续找一遍
	}
	return NULL;//条件不成立,返回空指针

}

int main()
{
	char arr1[] = "abcdefabcdef";
	char arr2[] = "cdef";
	char* ret = my_strstr(arr1, arr2);//传入实参
	if (ret == NULL)
		printf("没找到\n");
	else
		printf("%s\n", ret);
	return 0;
}

13、strtok函数的使用和实现


13.1 语法形式和注意事项


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

13.2 strtok函数的使用


#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>//strstr头文件

int main()
{
	char arr1[] = "yuuki@Outlook.com";
	char s[100] = { 0 };
	strcpy(s, arr1);//拷贝同一个需要查找的字符串

	const char* arr2 = "@.";//查找需要去除的字符
	char* ret = NULL;//设一个空指针接受strtok返回的字符串

	for (ret = strtok(s, arr2); ret != NULL; ret = strtok(NULL, arr2))//后面需要空指针接收
	{
		printf("%s\n", ret);
	}
	return 0;
}

14、 strerror函数的使用


14.1 语法形式和注意事项


char* strerror ( int errnum );
  • strerror函数可以把参数部分错误码对应的错误信息的字符串地址返回来
  • 在不同的系统和C语言标准库的实现中都规定了⼀些错误码,⼀般是放在"errno.h"这个头文件中说明
  • C语⾔程序启动时就会使用⼀个全局的变量errno来记录程序的当前错误码,只不过程序启动的时候errno是0,表示没有错误
  • 当我们在使用标准库中的函数的时候发⽣了某种错误,就会将对应的错误码,存放在errno中,每⼀个错误码都是有对应的错误信息
  • strerror函数就可以将错误对应的错误信息字符串的地址返回

对应0~10打印的结果如下:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<errno.h>

int main()
{
	for (int 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
10:  No child processes

14.2 示例


#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<errno.h>//strerror头文件

int main()
{
	//fopen以读的形式打开文件,若文件不存在,就打开失败

	//将文件传到pf,并打开pf
	FILE* pf = fopen("test.txt", "r");//文件为test.txt
	if (pf == NULL)
	{
		//若文件不存在,打印错误
		printf("%s\n", strerror(errno));
		return 1;
	}

	//关闭pf
	fclose(pf);

	return 0;
}

打印结果为:

No such file or directory//文件不存在

14.3 perror函数


14.4 语法形式和注意事项


void perror ( const char * str );
  • perror可直接打印错误信息
  • 打印信息前,前面会加上:与一个空格’ ’
  • 之后再加上错误信息
  • 注意:必须是个地址,空指针不行

14.5 示例


#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<errno.h>//strerror头文件

int main()
{
	//fopen以读的形式打开文件,若文件不存在,就打开失败

	//将文件传到pf,并打开pf
	FILE* pf = fopen("test.txt", "r");//文件为test.txt
	if (pf == NULL)
	{
		//zhangsan就是自定义信息,可加可不加
		perror("zhangsan");
		return 1;
	}

	//关闭pf
	fclose("zhangsan");

	return 0;
}

打印结果:

zhangsan: No such file or directory
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐