C.字符串处理

字符串处理函数详细文章:

C.strlen()函数-CSDN博客

C.strcpy()函数-CSDN博客

C.strcat()函数-CSDN博客

C.strcmp()函数-CSDN博客

C.strchr()函数-CSDN博客

C.strstr()函数-CSDN博客

文章目录

一. 字符串处理函数

1.1. strlen(求字符串长度)

1.2. strcpy (字符串拷贝)

1.3. strncpy (字符串拷贝带长度)

1.4. strcat (字符串追加)

1.5. strncat (字符串追加带长度)

1.6. strcmp (字符串比较)

1.7. strncmp 库函数

1.8. strchr (字符串查找字符)

1.9. strstr (字符串查找字串)

1.10. atoi/atol/atof (字符串转数值 )

1.11. strtok (字符串查找分割)

1.12. strerror (错误报告)

1.13. toupper (字符转大写)

1.14. tolower (字符转小写)

1.15. 其他常用(字符分类函数)

二. 字符串处理函数模拟

2.1. strcpy 模拟实现

2.2. strlen 模拟实现

2.3. strcat 模拟实现

2.4. strcmp 模拟实现

2.5. strchr 模拟实现

2.5. strstr 模拟实现

2.6. toupper 模拟实现

2.7. tolower 模拟实现


C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在常量字符串 中或者 字符数组 中。 ​ 字符串常量 适用于那些对它不做修改的字符串函数。

一. 字符串处理函数

1.1. strlen(求字符串长度)

参考文档:strlen - C++ Reference (cplusplus.com)

// 头文件<string.h>
size_t strlen(const char *s);
// s指 需要测量字符串的首元素地址
// 函数功能:
//			测字符指针 s 指向的字符串中字符的个数, 不包括’\0’
// 返回值: 
//			字符串中字符个数
  • 字符串已经 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包含 '\0' )。

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

  • 注意函数的返回值为size_t,是无符号的( 易错 )。

  • 学会strlen函数的模拟实现。

使用实例

#include <stdio.h>
#include <string.h>
#include <assert.h>

int main() {
	// 创建临时字符串:
	// 该字符串在内存存放的是:a b c d e f g \0
	char arr[] = { "abcdefg" };
	// 调用库函数strlen.
	size_t lenght = strlen(arr);
	// 打印结果:
	printf("%zu\n", lenght);
	return 0;
}

1.2. strcpy (字符串拷贝)

参考文档:strcpy - C++ Reference (cplusplus.com)

// 头文件<string.h>
char *strcpy(char *dest, const char *src);
// 函数的说明:
// 			拷贝 src 指向的字符串到 dest 指针指向的内存中, ’\0’也会拷贝
// 函数的返回值:
// 			目的内存的地址
// 注意: 在使用此函数的时候, 必须保证 dest 指向的内存空间足够大, 否则会出现内存污染。

char *strncpy(char *dest, const char *src, size_t n);
// 函数的说明:
// 			将 src 指向的字符串前 n 个字节, 拷贝到 dest 指向的内存中
// 返回值:
//			目的内存的首地址
// 注意:
// 			strncpy 不拷贝 ‘\0’
// 			如果 n 大于 src 指向的字符串中的字符个数, 则在 dest 后面填充 n-strlen(src)个 ’\0’

// dest:目的空间地址
// src:原字符串的首元素地址
  • 源字符串必须以 '\0' 结束。

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

  • 目标空间必须足够大,以确保能存放源字符串。

  • 目标空间必须可变。

  • 学会模拟实现 。

使用实例

#include <stdio.h>
#include <string.h>
#include <assert.h>

int main() {
	// 该字符串在内存存放的是:a b c d e f g \0
	// 创建临时字符串:
	char sourceArr[] = { "abcdefg" };
	char destinationArr[20];
	// 使用strcpy();
	strcpy(destinationArr, sourceArr);
	printf("sourceArr:= %s\n", destinationArr);

	return 0;
}

1.3. strncpy (字符串拷贝带长度)

char * strncpy ( char * destination, const char * source, size_t num );
  • 拷贝num个字符从源字符串到目标空间。

  • 如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。

1.4. strcat (字符串追加)

参考文档:strcat - C++ Reference (cplusplus.com)

// 头文件<string.h>
char *strcat(char *dest, const char *src);
// 函数功能:
// 			strcat 函数追加 src 字符串到 dest 指向的字符串的后面。 追加的时候会追加’\0’
// 注意: 
//			保证 dest 指向的内存空间足够大。
char *strncat(char *dest, const char *src, size_t n);
// 追加 src 指向的字符串的前 n 个字符, 到 dest 指向的字符串的后面。
// 注意如果 n 大于 src 的字符个数, 则只讲 src 字符串追加到 dest 指向的字符串的后面
// 追加的时候会追加’\0’
  • 源字符串必须以 '\0' 结束。

  • 目标空间必须有足够的大,能容纳

  • 目标空间必须可修改。

  • 字符串自己给自己追加,如何?

使用实例

#include <stdio.h>
#include <string.h>
#include <assert.h>

int main() {
	// 该字符串在内存存放的是:a b c d e f g \0
	// 创建临时字符串:
	char src[] = { "Word" };
	char dest[20] = "Hello ";
	// 调用strcat()函数.
	strcat(dest, src);
	printf("%s\n", dest);

	return 0;
}

1.5. strncat (字符串追加带长度)

char * strncat ( char * destination, const char * source, size_t num );

1.6. strcmp (字符串比较)

参考文档:strcmp - C++ Reference (cplusplus.com)

// 头文件<string.h>
int strcmp(const char *s1, const char *s2);
// 函数说明:
// 			比较 s1 和 s2 指向的字符串的大小,
// 			比较的方法: 逐个字符去比较 ascII 码, 一旦比较出大小返回。
// 			如过所有字符都一样, 则返回 0
// 返回值:
// 			如果 s1 指向的字符串大于 s2 指向的字符串 返回 1
// 			如果 s1 指向的字符串小于 s2 指向的字符串 返回-1
// 			如果相等的话返回 0
int strncmp(const char *s1, const char *s2, size_t n);
// 函数说明: 
//			比较 s1 和 s2 指向的字符串中的前 n 个字符

标准规定:

  • 第一个字符串大于第二个字符串,则返回大于0的数字。

  • 第一个字符串等于第二个字符串,则返回0。

  • 第一个字符串小于第二个字符串,则返回小于0的数字。

使用实例

#include <stdio.h>
#include <string.h>
#include <assert.h>

int main() {
	// 创建临时字符串:
	char arr1[20] = { "zhangsan" };
	char arr2[20] = { "zhangsanfeng" };
	// 比较规则:zz相等往下走.. nn相等往下走..f和\0不相等f大.
	int ret = strcmp(arr1, arr2);
	if (ret < 0)
		printf("<\n");
	else if (ret == 0)
		printf("==\n");
	else if (ret > 0)
		printf(">\n");

	return 0; 
}

1.7. strncmp 库函数

int strncmp ( const char * str1, const char * str2, size_t num );

1.8. strchr (字符串查找字符)

参考文档:strchr - C++ Reference (cplusplus.com)

#include <string.h>
char *strchr(const char *s, int c);
// 函数说明:
// 		在字符指针 s 指向的字符串中, 找 ascii 码为 c 的字符
// 		注意, 是首次匹配, 如果过说 s 指向的字符串中有多个 ASCII 为 c 的字符, 则找的是第 1 个字符
// 返回值:
// 		找到了返回找到的字符的地址,
// 		找不到返回 NULL,
char *strrchr(const char *s, int c);
// 函数的说明: 
// 			末次匹配在 s 指向的字符串中, 找最后一次出现的 ASCII 为 c 的字符,
// 返回值:
// 			末次匹配的字符的地址。
// 			strchr从前往后找 第一次出现c的地址,如果没找到 返回NULL

使用实例

#include <stdio.h>
#include <string.h>

void StrchrTest()
{
    char src[] = "Hello World!";
    char *findRet = strchr(src, 'W');
    if (findRet != NULL)
    {
        printf("%s\n", findRet);
    }
}
int main()
{
    StrchrTest();
    return 0;
}

1.9. strstr (字符串查找字串)

参考文档:strstr - C++ Reference (cplusplus.com)

#include <string.h>
char * strstr ( const char *str1, const char * str2);
char * strstr ( const char *str1, const char * str2);
// 函数说明:
// 			在 haystack 指向的字符串中查找 needle 指向的字符串, 也是首次匹配
// 返回值:
// 			找到了: 找到的字符串的首地址
// 			每找到: 返回 NULL
// 返回值:
//			找到返回找到的地址 失败 返回NULL
  • 返回str2在str1中第一次出现的指针,如果str2不是str1的一部分,则返回空指针。

使用实例

#include <stdio.h>
#include <string.h>
#include <assert.h>

int main() {
	char arr1[] = { "bbbbcaasklfghsa" };
	char arr2[] = { "bbc" };
	// 调用strstr()函数.
	char* ret = strstr(arr1, arr2);
	if (ret == NULL)
		printf("未找到相应的字串!\n");
	else 
		printf("%s\n", ret);

	return 0;
}

1.10. atoi/atol/atof (字符串转数值 )

// 头文件: #include <stdlib.h>
int atoi(const char *nptr);
long atol(const char *nptr);
long long atoll(const char *nptr);
long long atoq(const char *nptr);
double atof(const char *nptr);
// 函数的功能:
//			将 nptr 指向的字符串转换成整数, 返回

使用实例

#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>

void Ato_Test()
{
    printf("%d\n", atoi("1234"));
    printf("%ld\n", atol("12314123"));
    printf("%lld\n", atoll("3245234"));
    printf("%f\n", atof("3.2344"));
}

int main()
{
    Ato_Test();

    return 0;
}

1.11. strtok (字符串查找分割)

参考文档:strtok - C++ Reference (cplusplus.com)

char * strtok ( char * str, const char * sep );
// 第一次切割: str必须指向 待切割的字符串的首元素地址 delim指向分割符":"
// 后续切割:  str传NULL delim指向分割符":"
// 返回值:
// 			 成功:返回值子串的首元素地址
// 			 失败:返回NULL
  • sep参数是个字符串,定义了用作分隔符的字符集合

  • 第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标 记。

  • strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注: strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容 并且可修改。)

  • strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串 中的位置。

  • strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标 记。

  • 如果字符串中不存在更多的标记,则返回 NULL 指针。

使用实例

#include <stdio.h>
#include <string.h>
#include <assert.h>

int main() {
	char email[] = { "adasdsa@kgsdahgksldsajf.com" };
	char cp[50] = {0};
	strcpy(cp, email);

	// 接下来测试strtok()函数.
	char* ret = NULL;
	for (ret = strtok(cp, "@."); ret != NULL; ret = strtok(NULL, "@.")) {
		printf("%s\n", ret);
	}

	return 0;
}

-----------------------------------------------------------------------------------------

#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>

void StrtokTest()
{
    char str[] = "hehehe:xixixi:hahaha:lalala#heiheihei:henhenhen:wuwuwu";
    char *buf[32]; // 存放每一次切割后切出来数据的首元素地址.

    // 进行分割.
    size_t i = 0;
    buf[i] = strtok(str, ":");
    while (buf[i] != NULL)
    {
        ++i;
        buf[i] = strtok(NULL, ":");
    }

    // 进行遍历打印
    i = 0;
    while (buf[i] != NULL)
    {
        printf("%s\n", buf[i++]);
    }
}

int main()
{
    StrtokTest();

    return 0;
}

// 代码优化:

1.12. strerror (错误报告)

参考文档:strerror - C++ Reference (cplusplus.com)

char * strerror ( int errnum );
  • 返回错误码,所对应的错误信息。

使用实例

#include <stdio.h>
#include <string.h>
#include <errno.h>//必须包含的头文件

int main() {
	printf("%s\n", strerror(0));
	printf("%s\n", strerror(1));
	printf("%s\n", strerror(2));
	printf("%s\n", strerror(3));
	printf("%s\n", strerror(4));
	return 0;
}

1.13. toupper (字符转大写)

参考文档:toupper - C++ Reference (cplusplus.com)

int toupper ( int c );
  • 将字符转为大写.

使用实例

#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <ctype.h>

int main() {
	char ch = 'a';
	int ich = toupper(ch);
	printf("%c", ich);
	return 0;
}

1.14. tolower (字符转小写)

参考文档:tolower - C++ Reference (cplusplus.com)

int tolower ( int c );
  • 将字符转为小写.

使用实例

#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <ctype.h>

int main() {
	char ch = 'a';
	int ich = tolower(ch);
	printf("%c", ich);
	return 0;
}

1.15. 其他常用(字符分类函数)

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

二. 字符串处理函数模拟

2.1. strcpy 模拟实现

/* strcpy 模拟实现 */
#include <stdio.h>
#include <string.h>
#include <assert.h>

char* my_strcpy(char* destination, char* soure) {
	// 断言:保护两个指针形参.
	assert(destination && soure);
	// 保留destination的指针位置,便于返回,形成链式访问.
	char* pBegin = destination;
	while (*destination++ = *soure++);

	return pBegin;
}

int main() {
	// 该字符串在内存存放的是:a b c d e f g \0
	// 创建临时字符串:
	char src[] = { "abcdefg" };
	char dest[20];
	// 使用strcpy();
	my_strcpy(dest, src);
	printf("sourceArr:= %s\n", dest);

	return 0;
}

2.2. strlen 模拟实现

/*strlen 模式实现*/
#include <stdio.h>
#include <string.h>
#include <assert.h>

// 计数器法:
// 所谓计数器方法,顾名思义,就是创建一个临时变量count用来计数,遍寻字符串直到找到字符串结束标志’\0’,每循环找一次就count + 1,最后返回count就可以得到字符串长度了。
size_t my_strlen_1(const char* str) {
	// 断言指针变量不为NULL指针.
	assert(str);
	int count = 0;
	while (*str != '\0') {
		++count;
		++str;
	}

	return count;
}

// 递归法:
size_t my_strlen_2(const char* str) {
	// 断言指针变量不为NULL指针.
	assert(str);
	
	if (*str != '\0') {
		return 1 + my_strlen_2(str + 1);
	}
	else {
		return 0;
	}	
}

// 指针减去指针法
// 在一个数组中,指向两个元素的两个指针相减,得到的是这两个指针间的元素个数。
size_t my_strlen_3(const char* str) {
	// 断言指针变量不为NULL指针.
	assert(str);

	const char* end = str;
	while (*end != '\0')
		++end;

	return end - str;	// 高地址-低地址.
}

int main() {
	// 该字符串在内存存放的是:a b c d e f g \0
	// 创建临时字符串:
	char arr[] = { "abcdefg" };
	// 调用库函数strlen.
	size_t lenght = strlen(arr);
	size_t lenght1 = my_strlen_1(arr);
	size_t lenght2 = my_strlen_2(arr);
	size_t lenght3 = my_strlen_3(arr);
	// 打印结果:
	printf("%zu %zu %zu %zu\n", lenght, lenght1, lenght2, lenght3);

	return 0;
}

2.3. strcat 模拟实现

/* strcat 模拟实现 */
#include <stdio.h>
#include <string.h>
#include <assert.h>

char* my_strcat(char* destination, const char* soure) {
	// 断言:保护两个指针形参.
	assert(destination && soure);
	// 保留destination的指针位置,便于返回,形成链式访问.
	char* pBegin = destination;
	// 找到destination的\0的位置.
	while (*destination != '\0')
		++destination;
	// 将soure的每一个字符存入destination中.
	while (*destination++ = *soure++);

	return pBegin;
}

int main() {
	// 该字符串在内存存放的是:a b c d e f g \0
	// 创建临时字符串:
	char src[] = { "Word" };
	char dest[20] = "Hello ";
	// 调用strcat()函数.
	my_strcat(dest, src);
	printf("%s\n", dest);

	return 0;
}

2.4. strcmp 模拟实现

/* strcmp  模拟实现 */
#include <stdio.h>
#include <string.h>
#include <assert.h>

int my_strcmp(const char* str1, const char* str2) {
	// 断言:保护两个指针形参.
	assert(str1 && str2);
	// 比较原则:
	// -第一个字符串大于第二个字符串,则返回大于0的数字。
	// - 第一个字符串等于第二个字符串,则返回0。
	// - 第一个字符串小于第二个字符串,则返回小于0的数字。
	while (*str1 == *str2) {
		if (str1 == '\0')
			return 0;
		++str1;
		++str2;
	}
	
	// 程序走到这里说明是不等于的,要么是大于,要么是小于.
	return(*str1 - *str2);
}

int main() {
	// 创建临时字符串:
	char arr1[20] = { "zhangsan" };
	char arr2[20] = { "zhangsanfeng" };
	// 比较规则:zz相等往下走.. nn相等往下走..f和\0不相等f大.
	int ret = strcmp(arr1, arr2);
	if (ret < 0)
		printf("<\n");
	else if (ret == 0)
		printf("==\n");
	else if (ret > 0)
		printf(">\n");

	return 0; 
}

2.5. strchr 模拟实现

#pragma once
#include <stdio.h>
#include <assert.h>

/// <summary>
/// 字符串查找字符(模拟实现)
/// </summary>
/// <param name="s"></param>
/// <param name="c"></param>
/// <returns></returns>
char* my_strchr(char* s, int c)
{
	assert(s);

	char* p_begin = s;
	while (*p_begin != c)
	{
		if (*p_begin == '\0')
			return NULL;
		p_begin++;
	}

	return p_begin;
}


/// <summary>
/// 字符串查找字符(模拟实现)
/// </summary>
/// <param name="s"></param>
/// <param name="c"></param>
/// <returns></returns>
const char* my_const_strchr(const char* s, int c)
{
	assert(s);

	const char* p_begin = s;
	while (*p_begin != c)
	{
		if (*p_begin == '\0')
			return NULL;
		p_begin++;
	}

	return p_begin;
}

2.5. strstr 模拟实现

// str1 为字符串, str2 为子串.
char* my_strstr(const char* str1, const char* str2) {
	assert(str1 && str2);
	// 定义指向的指针.
	const char* s1 = str1;
	const char* s2 = str2;
	const char* p = s1;

	while (*s1 != '\0') {
		s1 = p;
		s2 = str2;
		// 首个字母相同.
		while (*s1 != '\0', *s2 != '\0' && *s1 == *s2) {
			++s1;
			++s2;
		}
		if (*s2 == '\0') {
			return (char*)p;
		}	
		// 上面循环没有对比成功.
		++p;
	}

	return NULL;
}

int main() {
	char arr1[] = { "bbbbcaasklfghsa" };
	char arr2[] = { "bbc" };
	// 调用strstr()函数.
	char* ret = my_strstr(arr1, arr2);
	if (ret == NULL)
		printf("未找到相应的字串!\n");
	else 
		printf("%s\n", ret);

	return 0;
}

2.6. toupper 模拟实现

int my_toypper(int c) {
	return c - 32;
}

int main() {
	char ch = 'a';
	int ich = my_toypper(ch);
	printf("%c", ich);
	return 0;
}

2.7. tolower 模拟实现

int my_tolower(int c) {
	return c + 32;
}

int main() {
	char ch = 'A';
	int ich = my_tolower(ch);
	printf("%c", ich);
	return 0;
}
  • 29
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值