C语言常见库函数详解——【字符/字符串函数及内存操作函数】(一)

发布时间:2023-01-30 09:00

目录

零、前言

一、字符串操作函数(长度不受限)

1.1 strlen——求字符串长度

1.2 strcpy——字符串拷贝

1.3 strcat——字符串追加

1.4 strcmp——字符串比较

二、字符串操作函数(长度受限)

2.1 strncpy

2.2 strncat

2.3 strncmp


零、前言

‘a’——字符 "abcdef"——字符串

C语言中并没有字符串类型,但有很多相关函数。

一、字符串操作函数(长度不受限)

1.1 strlen——求字符串长度

字符串"abcdef"其实储存的是a b c d e f \0 ,而对于strlen函数求其长度,则是从a开始数,一直数到\0停止,则可得到"abcdef"这个字符串长度为6。

#include 
#include 

int main()
{
    char arr[] = "abcdef";
    int len = strlen(arr);
    printf("%d", len);
}

这样输出的结果为6。

在MSDN上对strlen的介绍如下:

C语言常见库函数详解——【字符/字符串函数及内存操作函数】(一)_第1张图片

但如果你是这样初始化字符串的:char arr[] = {'a','b','c','d','e','f'};那么就会得到一个随机值。因为这样定义的话字符串并不以'\0'结束。如果是char arr[] = {'a','b','c','d','e','f','\0'};或者char arr[10] = {'a','b','c','d','e','f'};则可返回6。

【小结strlen注意事项】:

1.strlen返回的是以'\0'为结束的字符串的长度,即他计算的是'\0'前的字符个数!

2.strlen的返回值为size_t,是无符号的。所以就算strlen("abc")-strlen("abcdefg")结果也是大于0的。可以用>/<直接比较,或强制转换为别的类型如int的方法来解决这一问题。

【strlen的模拟实现】:

#include 
#include 
//1.计数器的方法
size_t my_strlen1(const char* str)  //用const保护指针所指内容使其更安全
{
	int count = 0;
	assert(str != NULL); //确保str不为空指针
	while (*str != '\0')  //没到\0就加一
	{
		count++;
		str++;
	}
	return count;
}

//2.递归的方法
size_t my_strlen2(const char* str)
{
    assert(str != NULL);
	if (*str == '\0')
		return 0;
	else
		return 1 + my_strlen2(str+1);
}

//3.指针-指针的方法
size_t my_strlen3(char* str)
{
    assert(str != NULL);
	char* p = str;
	while (*p != '\0')
		p++;
	return p - str;
}

int main()
{
	char arr[] = "abcdef";
	printf("%d %d %d", my_strlen1(arr), my_strlen2(arr), my_strlen3(arr));
	return 0;
}

1.2 strcpy——字符串拷贝

#include 
#include 
int main()
{
    char arr1[20] = {0};
    char arr2[] = "abcdef";
    strcpy(arr1, arr2);
    return 0;
}

这样就可以让arr1中复制为arr2的内容,即此时arr1的内容为"abcdef"(注意是包括\0的)会拷贝\0并且拷贝过\0后停下来。所以arr2即源字符串里必须有\0!如果没有,程序会崩溃。

C语言常见库函数详解——【字符/字符串函数及内存操作函数】(一)_第2张图片

【小结strcpy注意事项】:

1.源字符串必须有\0

2.会拷贝\0过去

3.目标空间必须足够大,以确保能存放源字符串。(不够大程序会崩溃报错,但能拷贝过去。但作为负责的程序员是不能让这种事发生滴!)

4.目标空间必须可修改

如 char* arr1 = "qwertyuiop";则arr1为常量字符串,常量是不可修改的!所以此时不能把东西拷贝到arr1里。

【strcpy的模拟实现】:

char* my_strcpy(char* dest, const char* src)
{
	assert(src && dest);  //同时assert了src和dest都不是NULL
	char* ret = dest;
	while (*dest++ = *src++)  //将src赋值过去,不是\0就继续,这样可以一口气把\0也拷贝过去,妙!
	{
		;
		
	}
	return ret;
}

int main()
{
	char arr1[20] = { 0 };
	char arr2[] = "abcdef";
	printf("%s", my_strcpy(arr1, arr2));
	return 0;
}

(补充:strcpy返回类型的设计是为了链式访问~)


1.3 strcat——字符串追加

int main()
{
    char arr1[20] = "abc";
    char arr2[] = "defg";
    strcat(arr1, arr2);
    return 0;
}

这个代码即可实现defg追加到abc后面。从目标字符串的\0向后追加,追加到源字符串的\0,并且把\0也追加过来。

C语言常见库函数详解——【字符/字符串函数及内存操作函数】(一)_第3张图片

【小结strcat注意事项】:

1.源字符串和目标字符串都必须有\0

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

3.目标空间必须可修改

【strcat的模拟实现】:

char* my_strcat(char* dest, const char* src)
{
	assert(dest && src);
	char* ret = dest;
	//找目标空间中的\0
	while (*dest)
	{
		dest++;
	}
	//拷贝
	while(*dest++ = *src++)
	{
		;
	}
	return ret;
}

int main()
{
	char arr1[20] = "abc";
	char arr2[] = "def";
	printf("%s", my_strcat(arr1, arr2));
	return 0;
}

(补充:如果用我模拟的strcat自己给自己追加即my_strcat(arr1,arr1);则会死循环。但库里的可能可以正常。)


1.4 strcmp——字符串比较

int main()
{
    char arr1[] = "abcdef";
    char arr2[] = "abq";
    printf("%d", strcmp(arr1, arr2));
    return 0;
}

不是比较字符串的长度,而是比较字符串中对应位置上的字符的大小。如果相同,就比较下一对,直到不同或都遇到\0。

C语言常见库函数详解——【字符/字符串函数及内存操作函数】(一)_第4张图片

 C语言常见库函数详解——【字符/字符串函数及内存操作函数】(一)_第5张图片

 【strcmp的模拟实现】:

int my_strcmp(const char* arr1, const char* arr2)
{
	assert(arr1 && arr2);
	while(*arr1 == *arr2)
	{
		if (*arr1 == '\0')
		{
			return 0;
		}
		arr1++;
		arr2++;
	}
	if (*arr1 > *arr2)
		return 1;
	else
		return -1;
}

int main()
{
	char arr1[20] = "abc";
	char arr2[] = "abq";
	printf("%d", my_strcmp(arr1, arr2));
	return 0;
}

strcpy strcat strcmp——都是长度不受限制的字符串函数

strncpy strncat strncmp——长度受限制的字符串函数(相对安全)


二、字符串操作函数(长度受限)

2.1 strncpy

C语言常见库函数详解——【字符/字符串函数及内存操作函数】(一)_第6张图片

比strcpy多了一个参数,代表要拷贝几个字符。

例如:

int main()
{
    char arr1[] = "abcdef";
    char arr2[] = "qwertyuiop";
    strncpy(arr1, arr2, 3);
    printf("%s\n", arr1);
    return 0;
}

此时输出即为qwedef。

如果源字符串长度小于需要拷贝的长度:

int main()
{
    char arr1[] = "abcdef";
    char arr2[] = "qwe";
    strncpy(arr1, arr2, 5);
    printf("%s\n", arr1);
    return 0;
}

结果为qwe,因为超出的部分会用\0填充。但尽量不要这样写。


2.2 strncat

C语言常见库函数详解——【字符/字符串函数及内存操作函数】(一)_第7张图片

 比strcat多了一个参数,代表要追加几个字符。

例如:

int main()
{
    char arr1[20] = "abcdef";
    char arr2[] = "qwertyuiop";
    strncat(arr1, arr2, 5);
    printf("%s\n", arr1);
    return 0;
}

输出为abcdefqwert。\0也会被追加过去并不算在追加的个数之内。如果源字符串长度小于需要追加的长度,则会补充\0。


2.3 strncmp

C语言常见库函数详解——【字符/字符串函数及内存操作函数】(一)_第8张图片

C语言常见库函数详解——【字符/字符串函数及内存操作函数】(一)_第9张图片

  比strcmp多了一个参数,代表要比较几个字符。

例如:

int main()
{
    char arr1[20] = "abcdef";
    char arr2[] = "qwertyuiop";
    int ret = strncmp(arr1, arr2, 5);
    printf("%d\n", ret);
    return 0;
}

应该输出一个小于零的数。

(补充:如果是单纯的字符串大小于号的比较 if("abcdef">"abc") 此时比较的是地址)


C语言常见库函数详解——【字符/字符串函数及内存操作函数】(一)的部分就到这里啦~更多精彩内容可见下一篇博客:C语言常见库函数详解——【字符/字符串函数及内存操作函数】(二)!欢迎大家多多交流!

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号