字符函数和字符串函数

strlen

  1. 测量长度: size_t strlen ( const char * str );
    字符串已以’\0’ 作为结束标志;strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包含 ‘\0’ );参数指向的字符串必须要以 ‘\0’ 结束。注意函数的返回值为size_t,为无符号型
#include<stdio.h>
int main()
{
	const char *str = "abc\0def";
	printf("%d\n", strlen(str));  //3
	return 0;
}
  1. 模拟实现
int Mystrlen(const char * str)  //计数
{
	int count = 0;
	while (*str)
	{	count++;
		str++;
	}
	return count;
}
int Mystrlen(char *s)  //指针-指针的方式
{
	char *p = s;
	while (*p != ‘\0)
		p++;
	return p - s;
}
int Mystrlen(const char * str)  //递归实现
{
    assert(str);
	if (*str == '\0')
		return 0;
	else
		return 1 + my_strlen(str + 1);
}

strcpy

  1. 拷贝: char * strcpy (char * destination, const char * source);
    源字符串必须以 ‘\0’ 结束;将源字符串中的 ‘\0’ 拷贝到目标空间;目标空间必须足够大,以确保能存放源字符串;目标空间必须可变。
#include<stdio.h>
#include<string.h>
int main()
{
	char str1[] = "abc\0def";
	const char str2[] = "def\0abc";
	strcpy(str1, str2);
	printf("%s\n", str1);  //输出def
	return 0;
}
  1. 模拟实现
#include<stdio.h>
#include<assert.h>
#include<string.h>
char *Mystrcpy(char *dest, const char*src)  //函数源字符串必须加const
{
	char *ret = dest;
	assert(dest);
	assert(src);
	while ((*dest++ = *src++));
	return ret;
}
int main()
{
	char str1[]="def";
	char str2[]="abc";
	printf("%s\n", Mystrcpy(str1, str2));  //输出abc
	return 0;
}

strcat

  1. 连接: char * strcat(char * destination, const char * source);
    目标空间必须足够大,能容纳下源字符串;目标空间必须可修改。
#include<stdio.h>
#include<string.h>
int main()
{
	char str1[] = "abc\0def";
	const char str2[] = "def\0abc";
	strcat(str1, str2);  //以'\0'截止
	printf("%s\n", str1);  //输出abcdef
	return 0;
}
  1. 模拟实现
#include<stdio.h>
#include<assert.h>
#include<string.h>
char *Mystrcat(char *dest, const char*src)
{
	char *ret = dest;
	assert(dest);
	assert(src);
	while (*dest)
		dest++;
	while ((*dest++ = *src++));
	return ret;
}
int main()
{
	char str1[] = "abcd\0def";
	const char str2[] = "def\0abc";
	Mystrcat(str1, str2);  //以'\0'截止
	printf("%s\n", str1);  //输出abcddef
	return 0;
}

strcmp

  1. 比较大小: int strcmp(const char* str1,const char* str2);
    第一个字符串大于第二个字符串,返回大于0的数字;第一个字符串小于第二个字符串,返回小于0的数字;相等则返回0。
#include<stdio.h>
#include<string.h>
int main()
{
	char str1[] = "abcd";
	char str2[] = "def";
	int ret = strcmp(str1, str2); 
	if (ret > 0)
		printf("第一个大\n");
	else if (ret < 0)
		printf("第二个大\n");
	else
		printf("相等\n");
	return 0;
}
  1. 模拟实现
#include<stdio.h>
#include<assert.h>
#include<string.h>
int MyStrcmp(const char*str1, const char*str2)
{
	assert(str1);
	assert(str2);
	while (*str1 == *str2)
	{
		if (*str1 == '\0');  //不能放在最后,两个字符串均为'\0'时不再需要比较
		{
			return 0;
		}
		str1++;
		str2++;
	}
	return *str1 - *str2;
}
int main()
{
	char str1[] = "abcd";
	char str2[] = "def";
	int ret = MyStrcmp(str1, str2); 
	if (ret > 0)
		printf("第一个大\n");
	else if (ret < 0)
		printf("第二个大\n");
	else
		printf("相等\n");
	return 0;
}

strncpy

  1. 拷贝(字符):char* strncpy(char* destination,constchar* source,size_t num);
    拷贝指定个字符从源字符串到目标空间;如果源字符串的长度小于num,则拷贝完源字符之后,在目标的后边追加0,直到指定个;拷贝最后一个字符不追加’\0’
#include<stdio.h>
#include<string.h>
int main()
{
	char str[20] = "asdfasdfsadfasd";
	strncpy(str,"Hello!",5);
	printf("%s\n", str);  //Hellosdfsadfasd
	getchar();
	return 0;
}
  1. 模拟实现
#include<stdio.h>
#include<assert.h>
#include<string.h>
char *MyStrncpy(char * str3, const char * str4, int count)
{
    assert(str3);
	assert(str4);
	while (count && (*str3++ = *str4++))
		count--;
	if (count)
		while (--count)
			*str3++ = '\0';
	return (str3);
}
int main()
{
	char str1[20] = "asdfasdfsadfasd";
	MyStrncpy(str1, "Hello!", 5);  //Hellosdfsadfasd
	printf("%s\n", str1);
	return 0;
}

strncat

  1. 连接(字符):char* strncat(char* destination,const char* source,size_t num);
    将指定个字符从源字符串连接到目标空间;如果源字符串的长度小于num,不追加0;连接最后一个字符追加’\0’
#include<stdio.h>
#include<string.h>
int main()
{
	char str[20] = "asnlgk";
	strncat(str, "Hello!", 5);  //asnlgkHello
	printf("%s\n", str); 
	return 0;
}
  1. 模拟实现
#include<stdio.h>
#include<assert.h>
#include<string.h>
char* MyStrncat(char* dest, const char* src, int n)
{
	assert(dest);
	assert(src);
	while (*dest)
		++dest;
	while (n)
	{
		if (*src == '\0') 
			break;
		*dest++ = *src++;
		--n;
	}
	*dest = '\0';  //在结果后面添加'\0',而不是用'\0'填充目标剩余空间
	return dest;
}
int main()
{
	char str[20] = "asnlgk";
	MyStrncat(str, "Hello!", 5);  //asnlgkHello
	printf("%s\n", str);  
	return 0;
}

strncmp

  1. 比较大小:int strncmp(const char* str1,const char* str2,size_t num);
    第一个字符串大于第二个字符串,返回大于0的数字;第一个字符串小于第二个字符串,返回小于0的数字;相等则返回0;比较到出现另个字符不一样或者一个字符串结束或者num个字符全部比较完。
#include<stdio.h>
#include<string.h>
int main()
{
	int ret1 = strncmp("acc", "abcd", 4);
	int ret2 = strncmp("abc", "abcd", 3);
	int ret3 = strncmp("abc", "abcd", 4);
	printf("%d\n", ret1);  //1
	printf("%d\n", ret2);  //0
	printf("%d\n", ret3);  //-1
	return 0;
}
  1. 模拟实现
#include<stdio.h>
#include<assert.h>
#include<string.h>
int  MyStrncmp(char* str1, char* str2, int a)
{
    int i = 0;
	assert(str1);
	assert(str2);	
	for (i = 0; i < a; i++)
	{
		if (*(str1 + i) > *(str2 + i))
			return 1;
		else if (*(str1 + i) == *(str2 + i))
			continue;
		else if (*(str1 + i) < *(str2 + i))
			return -1;
	}
	if (i == a)
		return 0;
}
int main()
{
	int ret1 = MyStrncmp("acc", "abcd", 4);
	int ret2 = MyStrncmp("abc", "abcd", 3);
	int ret3 = MyStrncmp("abc", "abcd", 4);
	printf("%d\n", ret1);  //1
	printf("%d\n", ret2);  //0
	printf("%d\n", ret3);  //-1
	return 0;
}

strstr

  1. 在字符串中查找子字符串:char* strstr(const char* ,const char* );
    在第一个字符串中查询含有第二个子字符串的内容
#include<stdio.h>
#include<string.h>
int main()
{
	char*p1 = "abc";
	char*p2 = "thaabcaedef";
	char*ret = strstr(p2, p1);
	printf("%s\n", ret);  //abcaedef
	return 0;
}
  1. 模拟实现
#include<stdio.h>
#include<assert.h>
char* MyStrstr(const char*str1, const char*str2)
{
	const char *s1 = str1; 
	const char *s2 = str2;
	const char *cp = str1;
	assert(str1);
	assert(str2);
	if (!*str2)  //若查找空字符串,直接返回子字符串
		return str1;
	while (*cp)
	{
		s1 = cp;  //将跳过字符的指针重新赋值,重新查找
		s2 = str2;  //将指针重新指向子字符串
		while (*s1 && *s2 && !(*s1 - *s2))  //当两个字符串均未结束且找到相同字符,继续查找
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')  //当子字符串结束时停止循环
			return cp;
		cp++;  //子字符串与源字符串有部分不完全相同时,跳过此时指向的第一个字符
	}
	return NULL;
}
int main()
{
	char*p1 = "abc";
	char*p2 = "thaabcaedef";
	char*ret = MyStrstr(p2, p1);
	printf("%s\n", ret);  //abcaedef
	return 0;
}

strtok

   char* strtok(char* str,const char* sep);  
          第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。strtok函
   数找到str中的下一个标记,并将其用\0结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符
   串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)strtok函数的第一个参数不为NULL,
   函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。strtok函数的第一个参数为NULL,函数将在同
   一个字符串中被保存的位置开始,查找下一个标记。
#include<stdio.h>
#include<string.h>
int main()
{
	char *str = "Seincfe@yeah.net";
	char arr[20] = { 0 };
	char *ret = NULL;
	char *p = "@.";
	strcpy(arr, str); 
	for (ret = strtok(arr, p); ret != NULL; ret = strtok(NULL, p))
	    //仅在第一次传参的时候传入arr的地址吗,如果使用while将会使每次传入的参数都是arr的地址
	    //strotk函数中有延长局部变量生存时间,自动记录节点
		printf("%s\n", ret);
	/*char arr[] = "Seincfe@yeah. net";
	printf("%s\n", strtok(arr, "@."));
	printf("%s\n", strtok(NULL, "@."));
	printf("%s\n", strtok(NULL, "@."));*/  //过于麻烦所以不考虑这种方法
	return 0;
}

strerro

   char* strerror(int errnum);  返回错误码,所对应的错误信息;检测错误。
#include<stdio.h>
#include<string.h>
#include<errno.h>
int main()
{
	FILE* pF = fopen("unexist.ent", "r");
	if (pF == NULL)
		printf("Erroropeningfileunexist.ent:%s\n", strerror(errno));  //errno:Lasterrornumber 
	fclose(pF);
	return 0;
}

memcpy

  1. 内存拷贝:void* memcpy(void* destination,constvoid* source,size_t num);
    遇到’\0’的时候并不会停下来;函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。(库函数中的memcpy可以实现memmove的功能,我们这里不实现memmove)
#include<stdio.h>
#include<string.h>
int main()
{
	int str1[] = { 1,2,3,4,5,6 };
	int str2[20] = { 0 };
	memcpy(str2, str1, 24);
	printf("%d\n", str2[0]);
	return 0;
}
  1. 模拟实现
#include<stdio.h>
#include<assert.h>
#include<string.h>
void* MyMemcpy(void* dest, const void* src, int count)
{
	void *ret = dest;
	assert(dest);
	assert(src);
	while (count--)
	{
		*(char*)dest = *(char*)src;  //按字节拷贝
		((char*)dest)++;
		((char*)src)++;
	}
	return ret;
}
int main()
{
	int str1[] = { 1,2,3,4,5,6 };
	int str2[20] = { 0 };
	MyMemcpy(str2, str1, 24);
	printf("%d\n", str2[0]);
	return 0;
}

memmove

  1. 内存拷贝:void* memmove(void* destination,const void* source,size_t num);
    和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的;如果源空间和目标空间出现重叠,就得使用memmove函数处理。
#include<stdio.h>
#include<string.h>
int main()
{
	int i = 0;
	int str1[] = { 1,2,3,4,5,6 };
	int str2[20] = { 20,19,18,17,16,15,14,13,12,11,10 };
	memmove(str2 + 5, str1, 24);
	for (i = 0; i < 20; i++)
		printf("%-3d", str2[i]);
	return 0;
}
  1. 模拟实现
#include<stdio.h>
#include<assert.h>
#include<string.h>
void* MyMemmove(void* dest, const void*src, int count)
{
	void *ret = dest;
	assert(src && dest);
	if (dest < src)  //从后往前拷贝
	{
		while (count--)
		{
			*(char*)dest = *(char*)src;  //按字节拷贝
			((char*)dest)++;
			((char*)src)++;
		}
	}
	else  //从前往后拷贝
		while (count--)
			*((char *)dest + count) = *((char*)src + count);
	return ret;
}
int main()
{
	int i = 0;
	int str1[] = { 1,2,3,4,5,6 };
	int str2[20] = { 20,19,18,17,16,15,14,13,12,11,10 };
	MyMemmove(str2 + 5, str1, 24);
	for (i = 0; i < 20; i++)
		printf("%-3d", str2[i]);
	return 0;
}

memcmp

  内存比较:int memcmp(const void* ptr1,const void* ptr2,size_t num);
  第一个字符串大于第二个字符串,返回大于0的数字;第一个字符串小于第二个字符串,返回小于0的数字,相等则返回0
#include<stdio.h>
#include<string.h>
int main()
{
	char str1[] = "DWgAOtP12df0";
	char str2[] = "DWGAOTP12DF0";
	int n = memcmp(str1, str2, sizeof(str1));  //按字节比大小,可选取字节长度
	printf("%d\n", n);
	return 0;
}

memset

  初始化函数:void *memset(void *s, int ch, size_t n);
  将已开辟内存空间s的首n个字节的值设为值ch。
#include <stdio.h>
#include <string.h>
int main() {
	char s[] = "Golden Global View";
	memset(s, 'G', 6);
	printf("%s", s);
	return 0;
}
  1. memset()函数常用于内存空间初始化,将某一块内存中的内容全部设置为指定的值,通常为新申请的内存做初始化工作;
  2. memset()的深刻内涵:用来对一段内存空间全部设置为某个字符,一般用在对定义的字符串进行初始化
    例如:memset(a,’\0’,sizeof(a));
  3. memset可以方便的清空一个结构类型的变量或数组;它是对较大的结构体或数组进行清零操作的一种最快方法。

附:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值