【C语言】字符/字符串+内存函数

目录

Ⅰ、字符函数和字符串函数

[1 .strlen](#1 .strlen)

2.strcpy

3.strcat

4.strcmp

5.strncpy

6.strncat

7.strncmp

8.strstr

9.strtok

10.strerror

11.字符函数

[12. 字符转换函数](#12. 字符转换函数)

Ⅱ、内存函数

[1 .memcpy](#1 .memcpy)

2.memmove

3.memcmp

4.memset


Ⅰ、字符函数和字符串函数

1 .strlen

函数原型:

注意事项:

1.字符串以 '\0' 作为结束标志 , strlen 函数返回的是在字符串中 '\0' 前面 出现的字符个数( 不包含 '\0' ) 。
2.参数指向的字符串 必须要以 '\0' 结束
3.注意函数的 返回值size_t ,是无符号的( 易错 )
4.学会 strlen 函数的模拟实现

模拟实现:三种方法(计数器,递归,指针-指针)

cpp 复制代码
//模拟实现strlen
//方法一:计数器
size_t my_strlen1(const char* str)
{
	char* st = str;
	size_t count = 0;
	while (*st++)
	{
		count++;
	}
	return count;
}
//方法二:递归
size_t my_strlen2(const char* str)
{
	if (*str == '\0')
		return 0;
	return 1 + my_strlen2(++str);//注意这里不能用   后置++
}
//方法三:指针-指针
size_t my_strlen3(const char* str)
{
	char* st = str;
	while (*st != '\0')
	{
		//printf("%p\n", str);//  从小地址往大地址编址
		st++;
	}
	return st-str;
}

2.strcpy

函数原型:

注意事项:

1.Copies the C string pointed by source into the array pointed by destination, including the
terminating null character (and stopping at that point).
2.源字符串 必须以 '\0' 结束
3.会将 源字符串 中的 '\0' 拷贝到 目标空间
4.目标 空间必须足够大 ,以确保能存放源字符串。
5.目标 空间必须可变
6.学会模拟实现。

模拟实现:

cpp 复制代码
//模拟实现strcpy
char* my_strcpy(char* dest, const char* src)
{
	assert(dest && src);
	char* cur = src; char *re = dest;
	while (*dest++ = *src++);
	return re;
}

3.strcat

函数原型:

注意事项:

1.Appends a copy of the source string to the destination string. The terminating null character
in destination is overwritten by the first character of source, and a null-character is included
at the end of the new string formed by the concatenation of both in destination.
2.源字符串 必须以 '\0' 结束
3.目标 空间 必须有 足够 的大,能容纳下源字符串的内容。
4.目标空间必须 可修改
5.字符串自己给自己追加,如何?不能,可能会 非法访问

模拟实现:

cpp 复制代码
//模拟实现strcat
char* my_strcat(char* dest, const char* src)
{
	assert(dest&&src);
	char* ret = dest;
	while (*dest != '\0')
		dest++;
	char* sr = src;
	while (*dest++ = *sr++);
	return ret;
}

4.strcmp

函数原型:

注意事项:

1.This function starts comparing the first character of each string. If they are equal to each
other, it continues with the following pairs until the characters differ or until a terminating
null-character is reached.
标准规定:
1.第一个字符串大于第二个字符串,则返回 大于0 的数字
2.第一个字符串等于第二个字符串,则返回 0
3.第一个字符串小于第二个字符串,则返回 小于0 的数字

模拟实现:

cpp 复制代码
//模拟实现strcmp
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;
}

5.strncpy

函数原型:

注意事项:

1.Copies the first num characters of source to destination. If the end of the source C string
(which is signaled by a null-character) is found before num characters have been copied,
destination is padded with zeros until a total of num characters have been written to it.
2.拷贝 num个字符 字符串到 目标空间
3.如果源字符串的长度 小于num ,则拷贝完源字符串之后,在目标的后边 追加0 ,直到 num 个

简单使用;

cpp 复制代码
//使用strncpy
int main()
{
	char buf[128] = "xxxxxxxxxxxxxxxxxxxxxxxxxxx";
	char* str = "abcdef";
	printf("%s\n", strncpy(buf, str,7 ));//没有超过就是n为多大就拷贝几个过去,
									//n如果超过了字符串的长度后面就进行补 '\0'

	return 0;
}

执行结果:

6.strncat

函数原型:

注意事项:

1.Appends the first num characters of source to destination, plus a terminating null-character.
2.If the length of the C string in source is less than num, only the content up to the terminating null-character is copied
3.如果 空间 不够,要报错
4.如果num比源字符串长,则紧追加 NULL之前 的字符

简单使用:

cpp 复制代码
//使用strncat
int main()
{
	char buf[128]="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
	buf[10] = '\0';		//从第一个'\0'开始拼接
	buf[20] = '\0';
	char* str = "abcdef";

	printf("%s", strncat(buf, str, 5));
	return 0;
}

执行结果:

7.strncmp

函数原型:

注意事项:

比较到出现另个字符不一样或者一个字符串结束或者num个字符全部比较完。

简单使用:

cpp 复制代码
/* strncmp example */
int main()
{
	char str[][5] = { "R2D2" , "C3PO" , "R2A6" };
	int n;
	puts("Looking for R2 astromech droids...");
	for (n = 0; n < 3; n++)
		if (strncmp(str[n], "R2xx", 2) == 0)
		{
			printf("found %s\n", str[n]);
		}
	return 0;
}

执行结果:

8.strstr

函数原型:

注意事项:

Returns a poin ter to the first occurrence of str2 in str1, or a null pointer if str2 is not part of
str1.

模拟实现:

cpp 复制代码
//strstr的模拟实现
char* my_strstr(const char* str1, const char* str2)
{

	while (*str1)
	{
		if (*str1 == *str2)
		{
			char* s1 = str1; char* s2 = str2;
			while (*s1 && *s2 && (*s1 == *s2))
			{
				s1++;
				s2++;
			}
			if (*s2 == '\0')
				return str1;
		}
		str1++;
	}
}

9.strtok

函数原型:

注意事项:

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

简单使用:

cpp 复制代码
//strtok使用
int main()
{
	char str[128] = "hyd@qwer.com.cn.edu.com";//注意这里必须是可修改的字符串,常量不能修改
	char* sep = "@.";
	char* ret = strtok(str, "@.");
	printf("%s\n", ret);
	while(ret=strtok(NULL,sep))
		printf("%s\n", ret);

	return 0;
}

执行结果:

10.strerror

函数原型:

注意事项:

返回错误码(errno),所对应的错误信息。

简单使用:

cpp 复制代码
//使用strerror
int main()
{
	FILE* fp = fopen("data.txt", "r");
	if (fp == NULL)
	{
		//printf("打开失败:%s\n", strerror(errno));//打印错误信息
		perror("打开失败");//类似于 printf+错误原因
	}
	else
		printf("文件打开成功\n");
	return 0;
}

执行结果:

11.字符函数

函数 如果他的参数符合下列条件就返回真(非0)
iscntrl 任何控制字符(1-31是控制字符,32-127是可打印字符)
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 任何可打印字符,包括图形字符和空白字符

12. 字符转换函数

int tolower ( int c );
int toupper ( int c );

简单使用:

cpp 复制代码
/* isupper example */
#include <stdio.h>
#include <ctype.h>
int main ()
{
  int i=0;
  char str[]="Test String.\n";
  char c;
  while (str[i])
 {
    c=str[i];
    if (isupper(c)) 
        c=tolower(c);
    putchar (c);
    i++;
 }
  return 0;
}

执行结果:

Ⅱ、内存函数

1 .memcpy

函数原型:

注意事项:

1.函数 memcpy 从 source 的位置开始向后复制 num 个字节的数据到 destination 的内存位置。
2.这个函数在遇到 '\0' 的时候并不会停下来。
3.如果 source 和 destination 有任何的重叠,复制的结果都是未定义的。

模拟实现:

cpp 复制代码
//模拟实现memcpy
char* my_memcpy(void* dest, const void* src,size_t sz)
{
	assert(dest && src);
	char* ret = dest;
	while (sz--)
	{
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
	return ret;
}

2.memmove

函数原型:

注意事项:

1.和 memcpy 的差别就是 memmove 函数处理的源内存块和目标内存块是可以重叠的。
2.如果源空间和目标空间出现重叠,就得使用 memmove 函数处理。

模拟实现:

cpp 复制代码
//char* my_memmove(void* dest, const void* src, size_t sz)
{
	assert(dest && src);
	char* ret = (char*)dest;
	if (dest < src)
	{
		while(sz--)
		{
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
	}
	else
	{
		while (sz--)
		{
			*((char*)dest + sz) = *((char*)src + sz);
		}
	}
}

3.memcmp

函数原型:

注意事项;

1.比较从 ptr1 和 ptr2 指针开始的 num 个字节
2.返回值如下:

简单使用:

cpp 复制代码
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7 };
	//01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00 06 00 00 00 07 00 00 00
	//
	int arr2[] = { 1,2,3,0x11223304 };
	//01 00 00 00 02 00 00 00 03 00 00 00 04 33 22 11
	int ret = memcmp(arr1, arr2, 13);
	printf("%d\n", ret);

	return 0;
}

执行结果:0

4.memset

函数原型:

注意事项:

字节为单位设置内存的

简单使用:

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

//	int arr[10] = { 0 };
//	memset(arr, 0, 40);

	return 0;
}

执行结果:hello xxxld

相关推荐
卑微求AC8 分钟前
(C语言贪吃蛇)11.贪吃蛇方向移动和刷新界面一起实现面临的问题
c语言·开发语言
程序猿小D21 分钟前
第二百六十七节 JPA教程 - JPA查询AND条件示例
java·开发语言·前端·数据库·windows·python·jpa
Yvemil726 分钟前
RabbitMQ 入门到精通指南
开发语言·后端·ruby
潘多编程36 分钟前
Java中的状态机实现:使用Spring State Machine管理复杂状态流转
java·开发语言·spring
冷静 包容1 小时前
C语言学习之 没有重复项数字的全排列
c语言·开发语言·学习
碳苯1 小时前
【rCore OS 开源操作系统】Rust 枚举与模式匹配
开发语言·人工智能·后端·rust·操作系统·os
结衣结衣.2 小时前
C++ 类和对象的初步介绍
java·开发语言·数据结构·c++·笔记·学习·算法
学习使我变快乐2 小时前
C++:静态成员
开发语言·c++
TJKFYY2 小时前
Java.数据结构.HashSet
java·开发语言·数据结构
杰哥在此2 小时前
Python知识点:如何使用Multiprocessing进行并行任务管理
linux·开发语言·python·面试·编程