【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

相关推荐
朝朝辞暮i6 小时前
C++ 第 23 课:class —— 开始真正进入面向对象
开发语言·c++·算法
小师兄吃牛肉7 小时前
C语言篇:宏
c语言·开发语言
郑同学的笔记7 小时前
【c++随笔28】strcmp 和 memcmp对比
开发语言·c++
炸膛坦客7 小时前
单片机开发工具篇:(十四)配置输出 .map 文件及其本地路径
c语言·单片机·嵌入式硬件
言乐67 小时前
Python根据无法识别搜索词找出可能输入内容模型
开发语言·python·django·virtualenv·pygame
weixin_307779138 小时前
有限产能智能排产与动态重排智能体:从需求解构到技术实现
开发语言·人工智能·算法·架构
kakakahahahaha8 小时前
Windows C盘临时文件清理:%temp%、Windows Temp、Prefetch、Windows.old与hiberfil.sys处理指南
c语言·开发语言·windows
朝朝辞暮i8 小时前
C++ 第 27 课:智能指针 shared_ptr
开发语言·c++·算法
朝朝辞暮i8 小时前
C++ 第 29 课:回调函数 Callback
开发语言·c++·算法
笨笨饿8 小时前
140_AI新手村MCP与Skills是干嘛的
开发语言·人工智能·python·stm32·单片机·嵌入式硬件·物联网