Day 16 字符串和字符函数2 3.31

strtok

char * strtok ( char * str , const char * sep );

sep参数是个字符串,定义了作分隔符的字符合集。

第一个参数指定一个字符串,他包含了0个或者多个由sep字符中一个或者多个分隔符的标记。

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

int main()
{
    char arr[] = "zpengwei@yeah.net";
    char buf[30] = {0};
    strcpy(buf,arr);

    const char *sep ="@.";
    strtok(buff,sep);
    //只找第一个标记。
    strtok(NULL,sep);
    //从保存好的位置继续找。
    
	printf("%s\n", strtok(buf, sep));//只找第一个标记
	printf("%s\n", strtok(NULL, sep));//是从保存的好的位置开始继续往后找
	printf("%s\n", strtok(NULL, sep));//是从保存的好的位置开始继续往后找

    return 0;
}

//strtok函数找到str中的下一个标记,并用‘\0’做结尾,返回一个指向这个标记的指针。
//在上面的代码就会把@替换成\0,然后返回最开始的地址也就是z的地址。
//strtok函数会改变被操纵的字符串,使用一般使用一个临时拷贝内容去操作而不是源内容。(buf的创建。)
//第一个参数,也就是现在的buf不为空指针的时候,会找到str的第一个标记,也就是@,改成\0后返回z。并记住@所在地址。
//第一个参数为空指针时

int main()
{
	char arr[] = "zpengwei@yeah.net.hehe@haha nihao";
	char buf[50] = { 0 }
	strcpy(buf, arr);

	const char* sep = "@. ";
	char* str = null;
	for (str=strtok(buf, sep); str!=null; str=strtok(null, sep))
    //赋值判断在操作。
	{
		printf("%s\n", str);
	}

	return 0;
}
//上面代码的另类写法。

strerror

char * strerror ( int errnum );

返回错误码锁定的错误信息。

	printf("%s\n", strerror(0));
	printf("%s\n", strerror(1));
	printf("%s\n", strerror(2));
	printf("%s\n", strerror(3));
//可以直接打印错误码信息。
#include <limits.h>
#include <errno.h>
#include <stdlib.h>

int main()
{
	int* p = (int*)malloc(INT_MAX);//想堆区申请内存的
	if (p == NULL)
	{
		printf("%s\n", strerror(errno));
	    //如果内存申请失败,返回错误信息。
        //perror("Malloc");   这个函数也会打印错误信息,打印格式为双引号之间的内容
        //加冒号也就是"Malloc":(错误信息),但是strerror没有,只有错误信息。
		return 1;
	}
	
	return 0;
}

字符分类函数简介

//如果参数符合以下就返回真。不是就返回假。

iscntrl    任何控制字符
isspace    空白字符:空格'',换页'\f',换行'\n',回车'\r',制表符'\t',垂直制表符'\v'
isdigit    十进制数字0-9
isxdigit   十六进制数字,包括所以十进制数字,小写字母a-f,大写字母A-F
islower    小写字母a-z
isupper    大写字母A-Z
isalpha    字母a-z或者A-z
isalnum    数字或者字母,a-z,A-Z,0-9
ispunct    标点符号,任何不属于数字或者字母的图形字符(可打印)
isgraph    任何图形字符
isprint    任何可打印字符,包括图形字符和空白字符

 大小写转换:

int main()
{
	char ch = 'A';
	putchar(toupper(ch));//转大写。
	putchar(tolower(ch));//转小写。

	return 0;
}

内存操作函数

memcpy

void *memcpy(void * dest, const void * src, size_t count);
//一个目标,一个源,一个拷贝字节大小。
//void*是为了适应各种类型,因此需要进行强制转换。

模拟实现

#include<stdio.h>
#include<assert.h>
#include<stdlib.h>

void* my_memcpy(void* dest, const void* src, size_t count)
{
	assert(dest && src);
	void* ret = dest;
	while (count--)
	{
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}

	return ret;
}


int main()
{
	char arr1[] = "1234abcd    ";
	char arr2[32];
	my_memcpy(arr2, arr1, strlen(arr1) + 1); 
	printf("arr2数组元素为:%s\n", arr2);
	return 0;
}

memmove

void *memmove( void *dest, const void *src, size_t count );

可以实现重叠内存的拷贝。

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

void* my_memmove(void* dest, const void* src, size_t count)
{
	assert(dest && src);
	void* ret = dest;
	//1
	if (dest < src)
	{
			while (count--)
			{
				*(char*)dest = *(char*)(src);
				dest = (char*)dest + 1;
				src = (char*)src + 1;
			}
	}
	else
	{
			while (count--)
			{
				*((char*)dest + count) = *((char*)src + count);
			}
	}

	return ret;
	//2
	if (dest > src && dest < ((char*)src + count))
	{
		//后->前
	}
	else
	{
		//前->后
	}
}

int main()
{
	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };

	my_memmove(arr1 + 2, arr1, 20);
	int i = 0;
	int sz = sizeof(arr1) / sizeof(arr1[0]);

	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr1[i]);
	}

	return 0;
}

模拟实现

void* my_memmove(void* dest, const void*src, size_t count)
{
	assert(dest && src);
	void* ret = dest;
	//1
	if (dest < src)
	{
		//前->后
		while (count--)
		{
			*(char*)dest = *(char*)(src);
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
	}
	else
	{
		//后->前
		while (count--)
		{
			*((char*)dest+count) = *((char*)src + count);
		}
	}

	return ret;
	//2
	if (dest > src && dest < ((char*)src + count))
	{
		//后->前
	}
	else
	{
		//前->后
	}
}

memcmp

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

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

大于是返回>1的数字。

等于则返回0。

小于是返回<1的数字。

int main()
{
	int arr1[] = { 1,2,3,4,5 };
	int arr2[] = { 1,2,3,4,0x11223305 };
	int ret = memcmp(arr1, arr2, 18);
    //比较第18个字节
	printf("%d\n", ret);

	return 0;
}

memset

void *memset( void *dest, int c, size_t count );

int main()
{
	int arr[] = { 0x11111111,0x22222222,3,4,5 };
	memset(arr, 6, 20);//memset是以字节为单位来初始化内存单元的,6是想设置成的数字,20是字节单位。

	return 0;
}

匿名结构体


struct
{
	char name[20];
	char id[12];
}ss;


struct
{
	char name[20];
	char id[12];
}*ps;

int main()
{
	ps = &ss;
	struct Book b1;
	struct Stu s2, s3;

	return 0;
}
//匿名结构体如果成员用于,在编译器看来也是不同的两个类型结构体。

typedef 类型重命名。

typedef struct Node
{
	int data;//数据
	struct Node* next;//指针
} Node ,*pNode;
//这样不用谢struct Node直接写Node就行了。
           struct Node*    pNode

结构体嵌套

struct Book
{
	char name[20];
	float price;
	char id[12];
}s = {"汪汪汪", 55.5f, "PGC001"};

struct Node
{
	struct Book b;
	struct Node* next;
};

int main()
{
	struct Book s2 = { "嗡嗡嗡", 66.6f, "HG001" };
	struct Node n = { {"哇哇哇", 66.8, "TG001"}, NULL};
	
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值