IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C语言——字符串函数和内存函数 -> 正文阅读

[C++知识库]C语言——字符串函数和内存函数

目录

一、字符串函数

1、strlen函数

strlen功能

strlen返回值

strlen函数注意事项

模拟实现strlen函数

2、strcpy函数

strcpy功能

strcpy返回值

strcpy注意事项

模拟实现strcpy函数

3、strcat函数

strcat功能

strcat返回值

strcat注意事项

模拟实现strcat函数

4、strcmp函数

strcmp功能

strcmp返回值

模拟实现strcmp函数

5、strncpy函数(受限制的字符串拷贝)

strncpy功能

strncpy返回值

6、strncmp函数

strncmp功能

strncmp返回值

7、strstr函数

strstr功能

strstr返回值

模拟实现strstr函数

8、strtok函数

strtok功能

二、内存函数

1、memcpy函数(没有内存重叠的时候使用)

memcpy功能

memcpy返回值

mamcpy注意事项

模拟实现memcpy函数

2、memmove函数(有内存重叠的时候使用)

memmove功能

memmove返回值

模拟实现memmove函数


一、字符串函数

1、strlen函数

strlen功能

获取字符串的长度

strlen返回值

每个函数都返回字符串中的字符数,不包括字符串的结束符。

我们来看一个例子

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
int main()
{
	char* str1 = "abc";
	char* str2 = "abcedf";
	if (strlen(str1) - strlen(str2) > 0)
	{
		printf("hehe\n");
	}
	else
	{
		printf("haha\n");
	}
	return 0;
}

输出结果为?

hehe

F:\VS编程文件\CProject\9月\test_9_16\Debug\test_9_16.exe (进程 7720)已退出,代码为 0。
按任意键关闭此窗口. . .

?strlen(str1)的结果是3,strlen(str2)的结果是6,所以是if的条件判断语句中,应该是3 - 6。但是不要忽略strlen函数返回的是size_t类型的数据,无符号整型,所以两个无符号整型运算之后的结果依然是无符号整型。因此,strlen(str1) -?strlen(str2) > 0,输出结果是hehe。

strlen函数注意事项

1、字符串已经 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包含 '\0' )。 ?

2、参数指向的字符串必须要以 '\0' 结束。

3、注意函数的返回值为size_t,是无符号的

模拟实现strlen函数

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <assert.h>
int my_strlen(const char* str)
{
	int count = 0;
	assert(str);
	while (*(str++))
	{
		count++;
	}
	return count;
}

int main()
{
	char str[] = { "abcdefg" };
	int ret = my_strlen(&str);
	printf("%d\n", ret);
	return 0;
}

2、strcpy函数

strcpy功能

复制字符串

strcpy返回值

函数返回目标字符串的地址。

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
int main()
{
	char str1[20] = "abcdef";
	char str2[] = "kpl";
	strcpy(str1, str2);
	printf("%s", str1);
	return 0;
}

输出结果:

kpl
F:\VS编程文件\CProject\9月\test_9_16\Debug\test_9_16.exe (进程 3724)已退出,代码为 0。
按任意键关闭此窗口. . .

strcpy注意事项

1、源字符串必须以 '\0' 结束。(没有'\0'strcpy函数就不知道什么时候拷贝结束了)

2、会将源字符串中的 '\0' 拷贝到目标空间。

3、目标空间必须足够大,以确保能存放源字符串。(防止造成越界访问)

4、目标空间必须是可被写的。(目标空间不能被const修饰)

模拟实现strcpy函数

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
char* my_strcpy(char* dest, const char* src)
{
	char* ret = dest;
	while (*dest++ = *src++)
	{
		;
	}
	return ret;
}
int main()
{
	char string[80];
	my_strcpy(string, "Hello world from ");
	strcat(string, "strcpy ");
	strcat(string, "and ");
	strcat(string, "strcat!");
	printf("String = %s\n", string);
	return 0;
}

在之前的博客中,有讲解过模拟strcpy函数,这里就不重复讲解了。

3、strcat函数

strcat功能

字符串追加

strcat返回值

返回的是目标字符串的地址。

#include <stdio.h>
#include <string.h>
int main()
{
	char str1[20] = "abcd";
	char str2[] = "efgh";
	char* ret = strcat(str1, str2);
	printf("%s", ret);
	return 0;
}

输出结果

abcdefgh
F:\VS编程文件\CProject\9月\test_9_16\Debug\test_9_16.exe (进程 15000)已退出,代码为 0。
按任意键关闭此窗口. . .

strcat注意事项

1、源字符串必须以 '\0' 结束。(没有结束标志会导致程序崩溃,因为程序不知道追加到哪里停止)

2、目标空间必须有足够的大,能容纳下源字符串的内容。

我们看到的str1的长度为5,明显只可以容纳str1的内容,不能再继续容纳str2的三个字符,这样会导致越界访问,造成程序的崩溃 ?

3、目标空间必须可修改。 (我们需要对目标空间进行字符串的追加,所以目标空间一定可以被修改,目标空间不能被const修饰)

模拟实现strcat函数

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
char* my_strcat(char* dest, char* src)
{
	char* ret = dest;
	//1、找到目标字符串的末尾\0
	while (*dest)
	{
		dest++;
	}
	//2、追加源字符串直到\0
	while (*dest++ = *src++)
	{
		;
	}
	return ret;
}
int main()
{
	char arr1[20] = { "abc" };
	char arr2[] = { "def" };
	char* ret = my_strcat(arr1, arr2);
	printf("%s\n", ret);
	return 0;
}

4、strcmp函数

strcmp功能

比较字符串大小?

strcmp返回值

?这个函数是两个字符串,从第一个字符开始逐一比较,若字符不相等则返回一个不等于0的整型(参照上述图标),若字符相等,则继续比较下一个字符,直到比较到两个字符串的结束符'\0'。

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
int main()
{
	char str1[] = "abcd";
	char str2[] = "abc";
	int ret = strcmp(str1, str2);
	printf("%d", ret);
	return 0;
}

输出结果

1
F:\VS编程文件\CProject\9月\test_9_16\Debug\test_9_16.exe (进程 13560)已退出,代码为 0。
按任意键关闭此窗口. . .

模拟实现strcmp函数

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int my_strcmp(const char* s1, const char* s2)
{
	while (*s1 && *s2)
	{
		if (*s1 == *s2)
		{
			s1++;
			s2++;
		}
		else
		{
			return *s1 - *s2;
		}
	}
	return 0;
}
int main()
{
	char string1[] = "The quick brown dog jumps over the lazy fox";
	char string2[] = "The QUICK brown dog jumps over the lazy fox";
	char tmp[20];
	int result;
	/* Case sensitive */
	printf("Compare strings:\n\t%s\n\t%s\n\n", string1, string2);
	result = my_strcmp(string1, string2);
	if (result > 0)
		strcpy(tmp, "greater than");
	else if (result < 0)
		strcpy(tmp, "less than");
	else
		strcpy(tmp, "equal to");
	printf("\tstrcmp:   String 1 is %s string 2\n", tmp);
	return 0;
}

5、strncpy函数(受限制的字符串拷贝)

strncpy功能

将源字符串中的n个字符拷贝到目标字符串当中

strncpy返回值

返回的是目标字符串的地址。

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
int main()
{
	char str1[20] = "abcd";
	char str2[] = "kpl";
	char* ret = strncpy(str1, str2, 2);
	printf("%s", ret);
	return 0;
}

输出结果

kpcd
F:\VS编程文件\CProject\9月\test_9_16\Debug\test_9_16.exe (进程 8276)已退出,代码为 0。
按任意键关闭此窗口. . .

注意事项:

1、被指定复制字符串的个数可以大于源字符串的长度。(被指定的元素可以是字符也可以是‘\0’

2、目标字符串必须足够大,以确保能存放源字符串。(防止造成越界访问)

3、目标字符串必须是可被修改的。

6、strncmp函数

strncmp功能

比较两个字符串中一定数量的字符。?

strncmp返回值

?比较的方法和strcmp是一样的。

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
int main()
{
	char str1[] = "abcd";
	char str2[] = "abkl";
	int ret1 = strncmp(str1, str2, 2);
	int ret2 = strncmp(str1, str2, 3);
	printf("%d\n", ret1);
	printf("%d\n", ret2);
	return 0;
}

7、strstr函数

strstr功能

?查找子串

strstr返回值

函数返回的是子串在目标字符串当中的地址。如果没有找到,则返回的是空指针,NULL。如果要查找的子串是长度为0的字符串,函数返回的是目标字符串的起始地址。

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
int main()
{
	char str1[] = "abcdefdgh";
	char str2[] = "d";
	char* ret = strstr(str1, str2);
	printf("%s", ret);
	return 0;
}

输出结果

defdgh
F:\VS编程文件\CProject\9月\test_9_16\Debug\test_9_16.exe (进程 6676)已退出,代码为 0。
按任意键关闭此窗口. . .

模拟实现strstr函数

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
char* my_strstr(char* p1, char* p2)
{
	char* s1;
	char* s2;
	char* pt = p1;
	if (*p2 == 0)
	{
		return p1;
	}
	while (*pt)
	{
		s1 = pt;
		s2 = p2;
		while (*s1 && *s2 && *s1 == *s2)
		{
			s1++;
			s2++;
		}
		if (*s2 == 0)
		{
			return pt;
		}
		pt++;
	}
	return NULL;
}
int main()
{
	char str[] = "lazy";
	char string[] = "The quick brown dog jumps over the lazy fox";
	char fmt1[] = "         1         2         3         4         5";
	char fmt2[] = "12345678901234567890123456789012345678901234567890";
	char* pdest;
	int  result;
	printf("String to be searched:\n\t%s\n", string);
	printf("\t%s\n\t%s\n\n", fmt1, fmt2);
	pdest = my_strstr(string, str);
	result = pdest - string + 1;
	if (pdest != NULL)
		printf("%s found at position %d\n\n", str, result);
	else
		printf("%s not found\n", str);
	return 0;
}

8、strtok函数

strtok功能

字符串分割函数

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

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
int main()
{
	char str1[] = "by@bite.cn";
	char str2[200] = { 0 };
	char sep[] = "@.";
	strcpy(str2, str1);
	char* ret = NULL;
	for (ret = strtok(str2, sep); ret != NULL; ret = strtok(NULL, sep))
	{
		printf("%s ", ret);
	}
}

输出结果

by bite cn
F:\VS编程文件\CProject\9月\test_9_16\Debug\test_9_16.exe (进程 1092)已退出,代码为 0。
按任意键关闭此窗口. . .

二、内存函数

1、memcpy函数(没有内存重叠的时候使用)

memcpy功能

拷贝内存空间的字符。

memcpy返回值

返回的是,目标内存的地址。之所以返回类型是void *,是因为该函数是以一个字节为单位进行拷贝的,并不知道拷贝的是整型、字符还是结构体。void *可以用来接收各种各样的地址。

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
int main()
{
	int arr1[100] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[100] = { 0 };
	int i = 0;
	memcpy(arr2, arr1, 10 * sizeof(int));
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr2[i]);
	}
	return 0;
}

输出结果

1 2 3 4 5 6 7 8 9 10
F:\VS编程文件\CProject\9月\test_9_16\Debug\test_9_16.exe (进程 12584)已退出,代码为 0。
按任意键关闭此窗口. . .

mamcpy注意事项

1、函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。

2、这个函数在遇到 '\0' 的时候并不会停下来。

3、如果source和destination有任何的重叠,复制的结果都是未定义的。

模拟实现memcpy函数

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <assert.h>
void* my_memcpy(void* dest, void* src, size_t n)
{
	void* ret = dest;
	assert(dest && src);
	while (n--)
	{
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
	return dest;
}
int main()
{
	char arr1[20] = { "123456789" };
	char arr2[20] = { "4567" };
	my_memcpy(arr1, arr2, 4);
	printf("%s\n", arr1);
	printf("%s\n", arr2);
	return 0;
}

2、memmove函数(有内存重叠的时候使用)

memmove功能

将一个内存区移动到另外一个

memmove返回值

?返回的是,目标内存的地址。

使用方法和memcpy是一样的。

模拟实现memmove函数

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <assert.h>
//模拟memmove函数
void* my_memmove(void *dest,const void *src,size_t n)//存在重叠部分的内存拷贝,优先拷贝重叠部分的内存
{
	void* ret = dest;
	assert(dest && src);
	if (dest < src)
	{
		while (n--)
		{
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
	}
	else
	{
		while (n--)
		{
			*((char*)dest + n) = *((char*)src + n);
		}
	}
	return ret;
}
//打印整形数组
void print(int* p, int sz)
{
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", p[i]);
	}
	printf("\n");
}
int main()
{
	int arr1[20] = { 1,2,3,4,5,6,7,8,9 };
	int arr2[20] = { 6,7,8,9 };
	my_memmove(arr1 + 2, arr1, 16);
	print(arr1, sizeof(arr1) / sizeof(arr1[0]));
	print(arr2, sizeof(arr2) / sizeof(arr2[0]));
	return 0;
}

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-09-23 11:16:21  更:2021-09-23 11:17:52 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/20 0:31:31-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码