C-字符(串)函数及内存函数-创新互联

目录

创新互联建站一直秉承“诚信做人,踏实做事”的原则,不欺瞒客户,是我们最起码的底线! 以服务为基础,以质量求生存,以技术求发展,成交一个客户多一个朋友!为您提供成都做网站、成都网站制作、成都外贸网站建设、成都网页设计、微信小程序开发、成都网站开发、成都网站制作、成都软件开发、重庆App定制开发是成都本地专业的网站建设和网站设计公司,等你一起来见证!

求字符串长度

头文件

strlen - 计算字符串长度

函数声明

strlen 函数模拟

PS.strlen计算出来的为无符号数,两个无符号数进行运算恒为正

长度不受限制的字符串函数

头文件

PS.此类函数只关注 '\0',使用时可能会越界访问

strcpy - 字符串拷贝

函数声明

strcpy 函数模拟

strcat - 字符串追加

函数声明

strcat 发生C4996错误解决

strcat 函数模拟

strcmp - 字符串比较

函数声明

strcmp 函数模拟

长度受限制的字符串函数

头文件

strncpy - 字符串拷贝

函数声明

strncat - 字符串追加

函数声明

strncmp - 字符串比较

函数声明

查找字符串

头文件

strstr - 查找字符串

函数声明

PS.NULL/null - 空指针        NUL/Null - '\0'

strstr 函数模拟

strtok - 拆解字符串

函数声明

字符串报错

头文件

strerror - 错误报告

函数声明

字符分类函数

头文件

字符转换函数

头文件

内存函数

头文件

memcpy - 拷贝函数

函数声明

memcpy 函数模拟(不包括内存重叠的情况)

memmove - 处理重叠拷贝函数

函数声明

memmove 函数模拟

memcmp - 比较函数

函数声明

memset - 内存设置函数

函数声明


求字符串长度 头文件
#include
strlen - 计算字符串长度 函数声明
size_t strlen (const char* str); //size_t == unsigned int

字符串以 '\0' 作为结束标志,strlen 函数返回的是在字符串中 '\0' 前面出现的字符个数

参数指向的字符串要以 '\0' 结束

#includeint main()
{
	char arr[] = { 'a','b','c' };
    //在后面加入'\0'时,就不会计算成随机值了
    //即:{ 'a','b','c','\0' }
	int len = strlen(arr);
	printf("%d", len);
	return 0;
}
strlen 函数模拟

指针

#include#include 
unsigned int strlen_s(char* str)
{ //此处 unsigned int 是符合原函数声明
  //写为 int 也可以
	int count = 0;
    assert(str != NULL);
	while (*str != '\0')
	{
		count++;
		str++;
	}
	return count;
}

递归

#includeint my_strlen(char* str)
{
    if (*str != '\0')
    {
        return 1 + strlen_s(str + 1);
    }
    else
    {
        return 0;
    }
}
PS.strlen计算出来的为无符号数,两个无符号数进行运算恒为正 长度不受限制的字符串函数 头文件
#include
PS.此类函数只关注 '\0',使用时可能会越界访问 strcpy - 字符串拷贝 函数声明
char* strcpy(char* destination, const char* source);

destination - 目标数组

source - 起始数组

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

目标字符串空间要足够大

目标空间大小要可修改

#include#includeint main()
{
	char arr1[] = "abcdefg";
	char arr2[] = "yes";
	strcpy(arr1, arr2);
	//拷贝的时候 '\0' 也会拷贝过去
	return 0;
}
strcpy 函数模拟
#include#include 
char* my_strcpy(char* dest, const char* src)
{
	assert(dest != NULL);
	assert(src != NULL);
	char* ret = dest;
    //拷贝 src 指向的字符串到 dest
	while (*dest++ = *src++)
	{
		;
	}
    //返回目的空间的起始地址
	return ret;
}
strcat - 字符串追加 函数声明
char* strcat(char* destination, const char* source);

追加字符串时是从第一个 '\0' 开始,源字符串中的 '\0' 也会追加过去

目标空间要足够大,能容纳下源字符串的内容

目标空间必须可以修改

字符串自己给自己追加时会出错,程序崩溃 

#include#includeint main()
{
	char ch1[20] = "Hello";
	char ch2[] = "World";
	strcat(ch1, ch2);
	printf("%s\n", ch1);
	return 0;
}
strcat 发生C4996错误解决

方法一:项目右键 - 属性 - C/C++ - 预处理器 - 预处理器定义 - 编辑,加上

     _CRT_SECURE_NO_DEPRECATE

方法二:在程序最前面加上

    #define _CRT_SECURE_NO_WARNINGS

strcat 函数模拟
#include#include 
char* my_strcat(char* dest, const char* src)
{
	assert(dest != NULL);
	assert(src != NULL);
	//两行代码可缩写为 assert(dest && src);
	char* ret = dest;
	while (*dest != '\0')
	{
		dest++;
	}
	while (*dest++ = *src++)
	{
		; //追加时的代码和 strcpy 一样
	}
	return ret;
}
strcmp - 字符串比较 函数声明
int strcmp(const char* str1, const char* str2);

str1 >str2,返回值 >0

str1 = str2,返回值 = 0

str1< str2,返回值< 0

比较首字符大小(根据ASCII码表比较),而非字符串长度

当首字符相等时,比较第二位字符,以此类推

#include#includeint main()
{
	char* p1 = "abc";
	char* p2 = "xyz";
	int a = strcmp(p1, p2);
	printf("%d\n", a);
	return 0; //打印 -1
}
strcmp 函数模拟
#include#include 
int my_strcmp(const char* str1, const char* str2)
{
	assert(str1 && str2);
	while (*str1 == *str2)
	{
		if (*str1 == '\0')
			return 0;
		str1++;
		str2++;
	}
	if (*str1 >*str2)
		return 1;
	else
		return -1;
}
#include#include 
int my_strcmp(const char* str1, const char* str2)
{
	assert(str1 && str2);
	while (*str1 == *str2)
	{
		if (*str1 == '\0')
			return 0;
		str1++;
		str2++;
	}
	return (*str1 - *str2);
}
长度受限制的字符串函数 头文件
#include
strncpy - 字符串拷贝 函数声明
char* strncpy(char* destination, const char* source, size_t count);

count - 拷贝的字节数 - 单位为字节

count 数字如果大于 source 字符个数,不足就补 '\0'

strncat - 字符串追加 函数声明
char* strcat(char* destination, const char* source, size_t count);

count - 追加的字节数 - 单位为字节

strncmp - 字符串比较 函数声明
int strcmp(const char* str1, const char* str2, size_t count);

count - 比较的字节数 - 单位为字节

如 count = 3,则各自比较前3个字符

查找字符串 头文件
#include
strstr - 查找字符串 函数声明
char* strstr(const char *haystack, const char *needle);

haystack - 要被检索的字符串

needle - 在 haystack 字符串内要搜索的小字符串

该函数返回在 haystack 中第一次出现 needle 字符串的位置,如果未找到则返回NULL - 空指针

打印时 %p - 找到返回地址,未找到返回NULL

  %s - 找到返回需要找的字符串及之后的字符串,未找到返回NULL

PS.NULL/null - 空指针        NUL/Null - '\0' strstr 函数模拟
#include#include 
char* my_strstr(const char* p1, const char* p2)
{
	assert(p1 && p2);
	char* s1, * s2;
	char* start = p1;
	//p1 为 const char* 类型,而 start 为 char* 类型
	//此处可将 p1 强制类型转换为 char* 类型
	while (*start)
	{
		s1 = start;
		s2 = p2;
		while ((*s1 != '\0') && (*s2 != '\0') && (*s1 == *s2))
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')
			return start;
		if (*s1 == '\0')
			return NULL;
		start++;
	}
	return NULL;
}
strtok - 拆解字符串 函数声明
char* strtok(char *str, const char *delim);

str - 要被分解成一组小字符串的字符串

delim - 包含分隔符的字符串  

该函数返回被分解的第一个子字符串,如果没有可检索的字符串,则返回一个NULL - 空指针

strtok 函数会拷贝一份源字符串,对拷贝的字符串进行拆解 

  • 当 strtok 函数的第一个参数为NULL时,函数将找到 str 中的第一个标记,strtok 函数将保存它在字符串中的位置
  • 当 strtok 函数的第一个参数不为NULL时,函数将在刚才的那个字符串中被保存的位置开始查找下一个标记,进行获取第二个、第三个子字符串
  • 当字符串中不存在更多的标记,则返回NULL - 空指针
#include#includeint main()
{
    char arr[] = "StarDustShakeHand@hotmail.com";
    const char* ch = "@.";
    char* ret;
    for (ret = strtok(arr, ch); ret != NULL; )
    {
        printf("%s\n", ret);
        ret = strtok(NULL, ch);
    }
    return 0;
}
字符串报错 头文件
#include
strerror - 错误报告 函数声明
char* strerror(int errnum);

输入错误码,返回错误信息

#include#includeint main()
{
    char* str = strerror(0);
    printf("%s\n", str);
    //打印 No error
    return 0;
}
#include#includeint main()
{
    char* str = strerror(1);
    printf("%s\n", str);
    //打印 Operation not permitted
    return 0;
}

错误码输入 errno,errno是一个全局的错误码变量,当C语言库函数在执行过程中发生了错误,就会把对应的错误码赋值到 errno 中

字符分类函数 头文件
#include
函数参数满足以下条件则返回真
iscntrl任何控制字符
isspace空白字符:空格;换页'\f';换行'\n';回车'\r',制表符'\t';垂直制表符'\v'
isdigit十进制数 0 ~ 9
isxdigit十六进制数 0 ~ 9;A ~ F;a ~ f
islower小写字母 a ~ z
isupper大写字母 A ~ Z
isalpha小写或大写字母
isalnum字母或十进制数字
ispunct标点符号,可打印的不属于数字或字母的图形字符
isgraph任何图形字符
isprint任何可打印的字符(包括图形、空白字符
字符转换函数 头文件
#include
函数用处
tolower将小写字符转为大写字符
toupper将大写字符转为小写字符
内存函数 头文件
#include//或者
#include

作用范围比字符串函数大,任何类型的数据都能操作

memcpy - 拷贝函数 函数声明
void* memcpy(void* destination, const void* source, size_t num);
  • memcpy 函数从 source 的位置开始向后复制 num 个字节的数据到 destination 的内存位置
  • 遇到 '\0' 时不会停下
  • 当 source 和 destination 有任何的重叠,复制的结果都是未定义的 

memcpy 处理内存不重叠的情况就行

memmove 要可以处理内存重叠的情况 

#include#includeint main()
{
    int arr1[] = { 1,2,3,4,5 };
    int arr2[5] = { 0 };
    memcpy(arr2, arr1, sizeof(arr1));
    return 0;
}
#include#includestruct Stu
{
    char name[20];
    int age;
};
int main()
{
    struct Stu arr1[] = { {"小明",18},{"小红",19},{"小刚",20} };
    struct Stu arr2[3] = { 0 };
    memcpy(arr2, arr1, sizeof(arr1));
    return 0;
}
memcpy 函数模拟(不包括内存重叠的情况)
#include#include 
void* my_memcpy(void* dest, const void* src, size_t num)
{
	assert(dest && src);
    char* ret = dest;
	while (num--)
		*((char*)dest)++ = *((char*)src)++;
	return ret;
} //dest 会改变,最好还是 void* ret
memmove - 处理重叠拷贝函数 函数声明
void* memmove(void* destination, const void* source, size_t num);

可处理内存重叠的情况

memmove 函数模拟
#include#include 
void* my_memmove(void* dest, const void* src, size_t num)
{	
	assert(dest && src);
    void* ret = dest;
	if (dest< src)
	{
		while (num--)
			*((char*)dest)++ = *((char*)src)++;
	}
	else
	{
		while (num--)
			*((char*)dest + num) = *((char*)src + num);
	}
	return ret;
} //dest 会改变,最好还是 void* ret
memcmp - 比较函数 函数声明
int memcmp(const void* ptr1, const void* ptr2, size_t num);

比较从 ptr1 和 ptr2 指针开始的 num 个字节,比出大小时就停止

ptr1 >ptr2,返回值 >0

ptr1 = ptr2,返回值 = 0

ptr1< ptr2,返回值< 0

#include#includeint main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[] = { 1,3,2,4,5,6,7,8,9,10 };
	int a = memcmp(arr1, arr2, 5);
    //a< 0
	return 0;
}
memset - 内存设置函数 函数声明
void* memset(void* str, int c, size_t n);

str - 指向要填充的内存块

c - 要被设置的值。该值以 int 形式传递,但在函数中时是使用该值的无符号字符形式

n - 要被设置为该值的字符数 - 单位为字节

#include#includeint main()
{
	char arr[10] = "";
	memset(arr, '#', 10);
	return 0;
}
#include#includeint main()
{
	int arr[10] = { 0 };
	memset(arr, 1, sizeof(arr));
	//元素都变为 16843009,memset 是一个字节一个字节地改
	return 0;
}

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


本文名称:C-字符(串)函数及内存函数-创新互联
文章出自:http://pwwzsj.com/article/icsoi.html