【C语言】_strncpy、strncat、strncmp

目录

1. 长度受限的字符串拷贝函数strncpy

1.1 strcpy与strncpy

1.2 strncpy函数的使用

1.2.1 关于\0的拷贝

1.2.2 关于\0的补位填充

2. 长度受限的字符串追加函数strncat

2.1 strcat与strncat

2.2 strncat的使用

2.2.1 关于\0的追加

2.2.2 关于\0的补位填充

3. 长度受限的字符串比较函数strcmp

3.1 strcmp与strncmp

3.2 strncmp的使用

4. 关于长度受限与长度不受限


关于字符串函数,已介绍过strlen、strcpy、strcat、strcmp等函数。

其中,strcpy、strcat、strcmp称为长度不受限制的字符串函数;

求字符串长度函数strlen相关文章如下:

【C语言】_字符串函数strlen-优快云博客icon-default.png?t=O83Ahttps://blog.youkuaiyun.com/m0_63299495/article/details/145134049长度不受限制的字符串函数文章链接分别如下:

字符串拷贝函数strcpy:

【C语言】_字符串函数strcpy-优快云博客icon-default.png?t=O83Ahttps://blog.youkuaiyun.com/m0_63299495/article/details/145136375 字符串追加函数strcat:

【C语言】_字符串函数strcat-优快云博客icon-default.png?t=O83Ahttps://blog.youkuaiyun.com/m0_63299495/article/details/145138951字符串比较函数strcmp:

本文介绍对应的另外一组函数:strncpy、strncat、strncmp,称为长度受限的字符串函数

1. 长度受限的字符串拷贝函数strncpy

1.1 strcpy与strncpy

相较于strcpy,strncpy增加了一个了一个类型为 size_t的参数num,

表示从源字符串进行拷贝的字符的最大个数;

1.2 strncpy函数的使用

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
int main() {
	char arr1[] = "hello world";
	char arr2[20] = { 0 };
	strncpy(arr2, arr1, 5);
	printf("%s\n", arr2);
	return 0;
}

运行结果如下:

1.2.1 关于\0的拷贝

对于待拷贝字符串src,是否会在要求的num个字符后再向dest中拷贝一个\0?

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
int main() {
	char arr1[] = "hello world";
	char arr2[20] = "xxxxxxxxxxxxxxxxxx";
	strncpy(arr2, arr1, 5);
	printf("%s\n", arr2);
	return 0;
}

调试监视arr2各元素值如下: 

可见:

对于strncpy,只拷贝src中要求的num个字母,并不会给拷贝后的num个字母后默认增加1个'\0'

1.2.2 关于\0的补位填充

若传递给strncpy的参数num大于待拷贝字符串src的有效长度,是否会在src后补位\0以满足要求的num?

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
int main() {
	char arr1[] = "hello world";
	char arr2[20] = "xxxxxxxxxxxxxxxxxx";
	strncpy(arr2, arr1, 15);
	printf("%s\n", arr2);
	return 0;
}

调试监视arr2数组的各元素:

可见:

对于strncpy,若传递给strncpy的参数num大于待拷贝字符串src的有效长度,则会在src后补位\0以满足要求的num个字符的拷贝

2. 长度受限的字符串追加函数strncat

2.1 strcat与strncat

相较于strcat,strncat增加了一个了一个类型为 size_t的参数num,表示追加的字符的最大个数;

2.2 strncat的使用

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
int main() {
	char arr1[] = "worldHELLOWORLD";
	char arr2[20] = "hello ";
	strncat(arr2, arr1, 5);
	printf("%s\n", arr2);
	return 0;
}

运行结果如下:

2.2.1 关于\0的追加

对于src字符串,在将其追加到dest字符串'\0'的位置之后,是否会在src字符串后默认追加一个\0?

测试思路为:初始化dest为不同于'\0'字符的其他字符串,本例采用x,为令src不从dest默认结尾处的\0处开始追加,在字符串中手动设置一个\0:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
int main() {
	char arr1[] = "worldHELLOWORLD";
	char arr2[20] = "hello\0xxxxxxxxxx";
	strncat(arr2, arr1, 5);
	printf("%s\n", arr2);
	return 0;
}

调试监视arr2数组各元素:

可见:

对于strncat,在将要求的来自src字符串的n个字符追加到dest字符串'\0'的位置之后,在src字符串后会默认追加一个\0

2.2.2 关于\0的补位填充

若追加完src中的有效字符且补充一个\0后,仍有待追加的位置,

即给定的字符追加参数num>(src有效字符数+额外填充的1个'\0'位),

那么余下的位置是否会继续填充'\0'?

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
int main() {
	char arr1[] = "worldHELLO";
	char arr2[20] = "hello\0xxxxxxxxxxxx";
	strncat(arr2, arr1, 14);
	printf("%s\n", arr2);
	return 0;
}

调试监视arr2数组各元素如下: 

可见:

对于strncat,当给定的字符追加参数num>(src有效字符数+额外填充的1个'\0'位),

dest余下的位置不会填充'\0'或其他字符,保持默认字符不变

3. 长度受限的字符串比较函数strcmp

3.1 strcmp与strncmp

相较于strcmp,strncmp增加了一个了一个类型为 size_t的参数num,

表示两个字符串进行比较的的字符的最大个数;

3.2 strncmp的使用

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
int main() {
	char arr1[] = "abcdef";
	char arr2[] = "abcddf";
	int ret1= strncmp(arr1, arr2, 4);
	int ret2 = strcmp(arr1, arr2, 6);
	printf("ret1=%d\n", ret1);
	printf("ret2=%d\n", ret2);
	return 0;
}

运行结果如下:

4. 关于长度受限与长度不受限

本文开篇已说明:

strcpy、strcat、strcmp称为长度不受限制的字符串函数;

strncpy、strncat、strncmp称为长度受限的字符串函数;

相比较而言,长度不受限制的字符串函数是不安全的,长度受限的字符串函数是相对安全的;

<think>好的,用户之前询问了strcat和strcmp的用法,现在他们想了解strncatstrncmp的用法。我需要参考之前提供的引用内容来回答这个问题。 首先,用户引用了四个资料,其中引用1、2、3提到了strncmpstrncatstrncpy的用法。特别是引用1中的示例代码展示了strncmp的比较方式,引用2是关于strncpy的,但可能与strncat有关联。引用3提到了strncatstrncmp,还有自定义的strstr函数,不过这可能不是重点。引用4虽然主要讲快速排序,但提到了strncatstrncmp的实现,可能涉及它们的内部机制。 用户现在需要的是strncatstrncmp的具体使用方法和示例代码。我需要确保回答结构清晰,符合之前用户要求的格式,比如分点说明、代码示例以及注意事项。同时,要遵循系统级指令,使用正确的中文和LaTeX格式,并在适当位置添加引用标记。 首先,解释strncat的功能,它用于将源字符串的前n个字符追加到目标字符串,并自动添加终止符。需要强调目标缓冲区必须有足够的空间,避免溢出。然后给出示例代码,可能参考引用1或4中的例子,但需要调整。例如,使用char数组初始化,然后调用strncat,并输出结果。 接下来是strncmp,比较两个字符串的前n个字符。返回值与strcmp类似,但只在指定长度内比较。示例代码可以类似引用1中的比较不同长度的情况,显示不同的返回值。需要注意用户可能对返回值何时为零或非零有疑问,需要明确说明。 注意事项部分要提到目标缓冲区大小和字符数n的关系,以及终止符的处理。比如,strncat保证追加后以\0结尾,而strncpy可能不会,但strncat会。此外,安全函数的优势,如防止缓冲区溢出,这也是用户可能关心的点。 示例代码需要正确展示函数的使用,比如在strncat中,目标数组足够大,src的内容被追加指定数量。在strncmp中,比较前n个字符,可能结果不同,如引用1中的例子,比较前4个字符返回0,前5个返回负数,需要正确解释。 最后,生成相关问题,可能涉及这些安全函数与原始函数的区别,手动实现原理,或者在具体场景中的应用。比如,如何用strncat连接字符数组的部分内容,或者strncmp在验证前缀时的使用。 需要检查是否所有引用都正确使用,特别是引用1和4中的内容。同时,确保代码示例没有错误,比如正确的头文件包含和语法。另外,用户之前的问题中提到过strcat和strcmp,所以需要与之前的回答保持一致,突出strncatstrncmp的不同之处,比如更安全的特性。 总结回答结构:先核心功能,函数原型,参数说明,示例代码,注意事项,扩展知识(如安全函数的重要性),最后相关问题。确保使用正确的格式,如代码块使用反引号,引用标记在适当的位置,如参数说明中的缓冲区大小注意事项引用之前的资料。</think>#### C语言`strncat`与`strncmp`函数详解 --- ### 一、核心功能 1. **`strncat`函数** - 将源字符串的前`n`个字符**追加**到目标字符串末尾,并自动添加终止符`\0` - **安全特性**:通过限定追加字符数量防止缓冲区溢出[^1][^4] 2. **`strncmp`函数** - 比较两个字符串的前`n`个字符的字典序,返回差异值 - **精确控制**:仅比较指定长度的字符,避免越界比较[^1][^3] --- ### 二、函数原型与参数 #### 1. `strncat`函数原型 ```c char *strncat(char *dest, const char *src, size_t n); // 返回目标字符串地址 ``` - **参数**: - `dest`:目标字符串(必须可修改且以`\0`结尾) - `src`:源字符串(追加内容) - `n`:最多追加的字符数(若`src`长度不足,则追加到`\0`为止) #### 2. `strncmp`函数原型 ```c int strncmp(const char *str1, const char *str2, size_t n); // 返回值为整数 ``` - **参数**: - `str1`/`str2`:待比较的字符串 - `n`:最多比较的字符数 - **返回值**: - 0:前`n`个字符完全相同 - >0:`str1`前`n`个字符字典序更大 - <0:`str2`前`n`个字符字典序更大 --- ### 三、使用示例 #### 1. `strncat`示例(安全字符串连接) ```c #include <stdio.h> #include <string.h> int main() { char dest[20] = "Hello"; // 预留足够空间 const char *src = " World!"; strncat(dest, src, 6); // 追加前6个字符(" World") printf("%s", dest); // 输出"Hello World" return 0; } ``` - **结果**:`Hello World`(仅追加`src`的前6个字符,忽略最后的`!`) #### 2. `strncmp`示例(部分字符比较) ```c #include <stdio.h> #include <string.h> int main() { const char *s1 = "apple_pie"; const char *s2 = "apple_juice"; int result = strncmp(s1, s2, 6); // 比较前6个字符 if (result == 0) { printf("前6字符相同"); // 输出此结果("apple_"相同) } else { printf("前6字符不同"); } return 0; } ``` --- ### 四、关键注意事项 | 函数 | 常见陷阱 | 解决方案 | |------------|--------------------------------------------------------------------------|-----------------------------------| | **strncat** | `n`超过`src`实际长度时,仍会追加到`src`的`\0`处 | 无需额外处理,函数自动终止[^4] | | **strncmp** | 比较时忽略`n`后的内容(如`strncmp("abc", "abcd", 3)`返回0) | 明确比较长度需求 | | **共用注意点** | 目标缓冲区大小需满足:`strlen(dest) + n + 1` ≤ 数组容量[^1] | 使用`sizeof`检查数组容量 | --- ### 五、扩展应用 - **`strncat`实战场景**: 拼接用户输入的部分内容(如仅取用户名前10个字符) ```c char username[20] = "user_"; strncat(username, input_data, 10); // 防止输入过长 ``` - **`strncmp`实战场景**: 验证协议头(如HTTP请求行是否以`GET`开头) ```c if (strncmp(request, "GET ", 4) == 0) { // 处理GET请求 } ``` --- ### 六、底层原理(引用自站内资料)[^1][^4] - **`strncat`实现逻辑**: 1. 找到目标字符串的`\0`位置 2. 复制`src`的前`n`个字符到目标末尾 3. 添加终止符`\0` - **`strncmp`实现逻辑**: 1. 逐字符比较ASCII码 2. 遇到`\0`或比较完`n`个字符时停止 3. 返回第一个差异字符的ASCII码差值 --- ### 相关问题 1. 如何用`strncat`实现分段拼接字符串? 2. `strncmp`比较时遇到`\0`会如何处理? 3. 为什么`strncat`比`strcat`更安全?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值