(21)从strerror到strtok:解码C语言字符函数的“生存指南2”


❤个人主页:折枝寄北的博客
❤专栏位置:简单入手C语言专栏

目录

  • 前言
  • [1. 错误信息报告](#1. 错误信息报告)
    • [1.1 strerror](#1.1 strerror)
  • [2. 字符操作](#2. 字符操作)
    • [2.1 字符分类函数](#2.1 字符分类函数)
    • [2.2 字符转换函数](#2.2 字符转换函数)
  • [3. 内存操作函数](#3. 内存操作函数)
    • [3.1 memcpy](#3.1 memcpy)
    • [3.2 memmove](#3.2 memmove)
    • 3.2memset
    • [3.3 memcmp](#3.3 memcmp)
  • 感谢您的阅读

前言

当你写下strcpy(dest, src)这行看似无害的代码时,是否意识到自己正在操作系统的血管里进行一场没有安全绳的高空走钢丝?在C语言的世界里,字符串从来都不是温顺的数据羔羊,而是戴着可爱面具的"内存刺客"------那些优雅的str开头的函数库,既是程序员最亲密的工具,也是引发段错误(Segmentation Fault)的经典元凶。

1. 错误信息报告

1.1 strerror

标准格式:

char * strerror ( int errnum );

功能:

获得指向错误信息的地址 C语言的库函数在运行的时候,如果发生错误,就会将错误存在一个变量中,这个(全局)变量是:errno

错误码是一些数字:1,2,4,5。。。 我们需要将错误码翻译成错误信息

代码示例部分:

示例一

复制代码
#include <stdio.h>
#include <string.h>
#include <errno.h>//必须包含的头文件
int main ()
{
  FILE * pFile;
  pFile = fopen ("unexist.ent","r");
  if (pFile == NULL)
    printf ("Error opening file unexist.ent: %s\n",strerror(errno));
    //errno: Last error number
  return 0;
}

示例二

复制代码
int main()
{
	printf("%s\n", strerror(0));
	printf("%s\n", strerror(1));
	printf("%s\n", strerror(2));
	printf("%s\n", strerror(3));
	printf("%s\n", strerror(4));
	printf("%s\n", strerror(5));

	return 0;
}


#include<errno.h>
int main()
{
	//打开文件
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		printf("%s\n",strerror(errno));
		//perror  打印错误信息
		//在打印错误信息前,会先打印自定义的信息
		perror("fopen");
		//printf("文件打开失败\n");
		return 1;
	}
	else
	{
		printf("文件打开成功\n");
	}
	//关闭文件
	fclose(pf);
	return 0;
	//如果文件打开成功,会返回一个有效的指针
	//打开失败,返回一个NULL指针
}

2. 字符操作

简单列举出部分字符操作函数,供大家自行学习。(全写出来篇幅过长,不易阅读)

2.1 字符分类函数

函数 --------如果他的参数符合下列条件就返回真

1.iscntrl----- 任何控制字符

2.isspace -----空白字符:空格' ',换页'\f',换行'\n',回车'\r',制表符'\t'或者垂直制表符'\v'

3.isdigit---- 十进制数字 0~9

4.isxdigit ----十六进制数字,包括所有十进制数字,小写字母a-f,大写字母A~F

5.islower---- 小写字母a~z

6.isupper ----大写字母A~Z

7.isalpha ----字母a-z或A~Z

8.isalnum ----字母或者数字,a-z,A-Z,0~9

9.ispunct ----标点符号,任何不属于数字或者字母的图形字符(可打印)

10.isgraph ----任何图形字符

11.isprint ----任何可打印字符,包括图形字符和空白字符

2.2 字符转换函数

int tolower ( int c );

int toupper ( int c );

代码示例:

复制代码
字符转换
eg:I Have Apple.
int main()
{
	char arr[] = "I Have Apple.";
	int i = 0;
	while (arr[i])
	{
		if (isupper(arr[i]))
		{
			arr[i] = tolower(arr[i]);
		}
		printf("%c", arr[i]);
		i++;
	}
	return 0;
}

3. 内存操作函数

3.1 memcpy

标准格式:

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

功能:

strcpy只能拷贝字符串

memcpy可以拷贝其他类型的数据

注意:

  • 函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。

  • 这个函数在遇到 '\0' 的时候并不会停下来。

  • 如果source和destination有任何的重叠,复制的结果都是未定义的。
    代码示例部分:

    #include <stdio.h>
    #include <string.h>
    struct
    {
    char name[40];
    int age;
    } person, person_copy;
    int main ()
    {
    char myname[] = "Pierre de Fermat";
    /* using memcpy to copy string: /
    memcpy ( person.name, myname, strlen(myname)+1 );
    person.age = 46;
    /
    using memcpy to copy structure: */
    memcpy ( &person_copy, &person, sizeof(person) );
    printf ("person_copy: %s, %d \n", person_copy.name, person_copy.age );
    return 0;
    }

3.2 memmove

标准格式:

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

功能及注意:

1.和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。

2.如果源空间和目标空间出现重叠,就得使用memmove函数处理。

代码示例部分:

复制代码
include <stdio.h>
#include <string.h>
int main ()
{
  char str[] = "memmove can be very useful......";
  memmove (str+20,str+15,11);
  puts (str);
  return 0;
}

3.2memset

功能:

以字节为单位来设置内存中的数据

代码示例部分:

复制代码
int main()
{
	char arr[] = "hello world";
	memset(arr, 'x', 5);
	printf("%s\n", arr);
	memset(arr+6, 'y', 5);
	printf("%s\n", arr);

	return 0;
}

3.3 memcmp

标准格式:

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

功能:

比较从ptr1和ptr2指针开始的num个字节

代码示例部分:

复制代码
#include <stdio.h>
#include <string.h>
int main ()
{
  char buffer1[] = "DWgaOtP12df0";
  char buffer2[] = "DWGAOTP12DF0";
  int n;
  n=memcmp ( buffer1, buffer2, sizeof(buffer1) );
  if (n>0) printf ("'%s' is greater than '%s'.\n",buffer1,buffer2);
  else if (n<0) printf ("'%s' is less than '%s'.\n",buffer1,buffer2);
  else printf ("'%s' is the same as '%s'.\n",buffer1,buffer2);
  return 0;
}

感谢您的阅读

相关推荐
whoarethenext41 分钟前
qt的基本使用
开发语言·c++·后端·qt
atec20001 小时前
使用uv管理python项目环境
开发语言·python·uv
是僵尸不是姜丝3 小时前
每日算法:洛谷U535992 J-C 小梦的宝石收集(双指针、二分)
c语言·开发语言·算法
小画家~4 小时前
第二十二: go与k8s、docker相关编写dockerfile
开发语言·golang·kubernetes
anlogic4 小时前
Java基础 4.12
java·开发语言
海涛高软4 小时前
qt mapFrom返回的QPoint和event->pos()区别和globalPos区别
开发语言·qt·命令模式
lauo4 小时前
智体知识库:ai-docs对分布式智体编程语言Poplang和javascript的语法的比较(知识库问答)
开发语言·前端·javascript·分布式·机器人·开源
xiegwei4 小时前
Kotlin 和 spring-cloud-function 兼容问题
开发语言·kotlin·springcloud
Alt.95 小时前
SpringMVC基础二(RestFul、接收数据、视图跳转)
java·开发语言·前端·mvc
念九_ysl6 小时前
深入解析Java内存与缓存:从原理到实践优化
java·开发语言·缓存