strcat函数
在C语言中,strcat()
函数用于将一个字符串追加在另一个字符串的末尾。
函数原型如下:
char *strcat(char *destination, const char *source);
参数解释:
destination
:目标字符串,将会追加在末尾。source
:源字符串,将会被追加到目标字符串的末尾。
函数返回值:
- 返回指向目标字符串的指针。
这个函数将源字符串追加到目标字符串后面,目标中的终止字符‘\0’会被源字符的第一个字符覆盖。
使用示例:
#include <stdio.h>
#include <string.h>
int main() {
char str1[20] = "Hello ";
char str2[] = "world!";
strcat(str1, str2);
printf("%s\n", str1);
return 0;
}
输出结果:
Hello world!
注意点
目标空间必须含\0,源字符串必须含\0
strcat在给目标字符串追加字符时,首先就要找到目标字符串中'\0'的位置,并在'\0'的位置上向后追加,为不是直接追加到目标字符串的末尾
我们来看以下代码
#include<stdio.h> #include<string.h> int main() { char arr1[20] = "hello\0XXXXXXXX"; char arr2[] = "bit"; strcat(arr1, arr2); printf("%s", arr1); return 0; }
运行结果
hellobit
arr2是从arr1中第一个'\0'位置,开始追加的。同时还把arr2中的'\0'追加到arr1中
当我们不在目标字符串里添加‘\0’,使用strcat函数就会出现错误,打印源字符串甚至会出现乱码
看个例子
char arr1[] = { 'h','e','l' }; char arr2[] = "bit"; strcat(arr1, arr2); printf("%s", arr1);
运行结果是
并且系统还报错了
目标空间必须足够大
当目标字符串剩余空间容不下源字符串时,编译器就会出现警告
我们看个例子
char arr1[5] = { 'h','e','l' }; char arr2[] = "bit"; strcat(arr1, arr2); printf("%s", arr1);
结果就是
自己给自己追加会陷入死循环
我们不能做出下面这种行为
const char a[10]="abc"; strcat(a,a);
目标空间必须可改
我们来看一下下列代码
#include<stdio.h> #include<string.h> int main() { char* arr1 = "hello"; char arr2[] = "bit"; strcat(arr1, arr2); printf("%s", arr1); return 0; }
当我们运行时,编译器会一直运行知道崩溃!为什么呢?因为这里arr1是个字符型指针,arr1所指向的字符是个常量字符不能改变,所以这种情况运行时编译器也会崩溃。
模拟实现
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <assert.h>
char* my_strcat(char* dest, const char* str)
{
char* ret = dest; // 保存dest的原始地址,以便后续返回
assert(*dest != NULL); // 断言检查dest是否是一个有效的非空指针
assert(*str); // 断言检查str是否是一个有效的非空指针,且其指向的字符串不为空
// 找到目的字符串里的'\0'
while (*dest != '\0') // 循环直到找到dest字符串的结束标志'\0'
{
dest++; // 移动dest指针到下一个字符位置
}
// 追加
while (*dest++ = *str++) // 这是一个复合赋值表达式,它同时做两件事:
// 1. 将str指向的字符赋值给dest指向的位置
// 2. 将dest和str都向前移动一个字符位置
{
; // 这里是一个空语句,因为复合赋值表达式本身已经完成了所有工作
}
return ret; // 返回dest的原始地址,也就是拼接后的字符串的起始地址
}
int main()
{
char arr1[30] = "hello";
char arr2[] = "world";
my_strcat(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
strncat
和strcat的关系
strncat
和strcat
都是C语言中的字符串处理函数,用于连接两个字符串,但它们在使用方式和安全性方面存在一些重要的区别。
-
功能:
strcat
函数用于将一个字符串(源字符串)追加到另一个字符串(目标字符串)的末尾,从而实现字符串的拼接。它会将源字符串中的每个字符逐个复制到目标字符串的末尾,直到遇到源字符串的结束符\0
为止。最后,在目标字符串的末尾添加一个结束符\0
,以确保拼接后的字符串是一个有效的字符串。strncat
函数与strcat
类似,但它只将源字符串的前n个字符追加到目标字符串的末尾。这通过第三个参数n
来实现,该参数指定了要追加的字符数量。
-
安全性:
strcat
函数在使用时需要格外小心,因为它不对目标字符串的缓冲区大小进行检查。如果目标字符串的缓冲区不足以容纳源字符串的内容,那么就会发生缓冲区溢出,这可能会导致程序崩溃或更严重的安全问题。strncat
函数则提供了更好的安全性,因为它允许你指定要追加的字符数量。这可以防止缓冲区溢出,因为你可以确保只追加足够数量的字符以适应目标字符串的缓冲区。
-
参数:
strcat
函数只有两个参数:目标字符串和源字符串。strncat
函数有三个参数:目标字符串、源字符串和要追加的字符数量。
总的来说,虽然strncat
和strcat
都用于连接字符串,但strncat
提供了更好的安全性,因为它允许你指定要追加的字符数量,从而防止缓冲区溢出。在使用这些函数时,你应该根据你的具体需求和安全考虑来选择使用哪一个。
strncat函数
C语言中的strncat函数用于将一个字符串追加到另一个字符串的末尾,并且指定追加的字符数。
函数原型如下:
char *strncat(char *dest, const char *src, size_t n);
参数说明:
dest
:目标字符串的指针,即要将源字符串追加到的字符串。src
:源字符串的指针,即要追加的字符串。n
:要追加的字符数。
返回值:
- 返回一个指向目标字符串的指针。
strncat 函数的行为如下:
- 它首先找到 dest 字符串的末尾,即找到第一个 \0 字符。
- 然后,它将 src 字符串的前 n 个字符(或直到遇到 \0,如果 src 字符串在 n 个字符之前结束)追加到 dest 字符串的末尾。
- 在追加字符后,dest 字符串的末尾会加上一个新的 \0 字符,以确保它是一个有效的 C 字符串。
使用示例:
#include <stdio.h>
#include <string.h>
int main() {
char str1[20] = "Hello";
char str2[10] = "World";
strncat(str1, str2, 3);
printf("%s\n", str1);
return 0;
}
输出结果:
HelloWor
上述示例中,首先定义了两个字符数组str1
和str2
,分别用来存储目标字符串和源字符串。然后使用strncat
函数将str2
中的前3个字符追加到str1
的末尾,结果为HelloWor
。
注意点
char *strncat(char *dest, const char *src, size_t n);
-
dest要有足够的空间来容纳要拷贝的字符串
-
strncat会将dest字符串最后的’\0’覆盖掉,字符追加完成后,再追加’\0’
-
如果num大于字符串src的长度,那么仅将src全部追加到dest的尾部;
如果num小于字符串src的长度,该字符会将src的所有字符附加在dest末尾。
无论哪种情况,都会在新字符串的末尾添加空字符。
与strcat的区别
大家可以先对比一下两个函数:
char* My_strcat(char* dest, const char* src)
char* My_strncat(char* dest, const char* src, int n)
1、strcat()增加字符串的结束条件是src == ‘\0’;
strncat的循环结束的条件则是所要追加的字符串个数为0;
2、strcat() 函数把源字符串整个连接到目标字符串的后面;
strcat()方便之处在于只用传两个参数可以实现,比较简便;
strncat()用来连接源字符串的前n个字符到目标字符串后,所以要多传一个参数n
3、strcat本质上是把目标字符串的’\0’与源字符串的元素交换实现的,当连接的是自己的时候,就 会陷入死循环,那么这时只能使用strncat函数了
模拟实现
实现strncat函数需要我们遵循该函数的标准行为,即:将源字符串src的前n个字符追加到目标字符串dest的末尾,并确保结果字符串以空字符\0结尾。以下是一个简单的strncat函数的实现:
#include <stddef.h> // 包含 size_t 类型定义
char *my_strncat(char *dest, const char *src, size_t n) {
char *orig_dest = dest; // 保存dest的原始指针
// 寻找dest字符串的末尾
while (*dest) {
dest++;
}
// 追加src的前n个字符到dest末尾
while (n-- && *src) {
*dest++ = *src++;
}
// 添加结束符'\0'
*dest = '\0';
// 返回原始dest指针
return orig_dest;
}
这个实现首先保存了dest的原始指针在orig_dest中,以便在函数结束时返回。然后,它遍历dest字符串直到找到空字符\0,这是字符串的结束标志。接下来,它循环n次(或直到src字符串结束,以先发生者为准),并将src的字符复制到dest的末尾。最后,它在追加的字符后面添加一个空字符\0,以确保结果是一个有效的C字符串。
使用这个函数时,你应确保dest指向的缓冲区足够大,以容纳追加的字符和结束符\0。如果dest缓冲区太小,将会发生缓冲区溢出,这可能导致程序崩溃或安全漏洞。
下面是一个使用my_strncat函数的例子:
#include <stdio.h>
int main() {
char buffer[50] = "Hello";
const char *addition = ", World!";
size_t n = 5; // 假设我们只想追加前5个字符
my_strncat(buffer, addition, n);
printf("%s\n", buffer); // 输出: Hello, Wor
return 0;
}
在这个例子中,buffer最初包含字符串"Hello"。我们调用my_strncat来追加addition字符串的前5个字符(即", Wor")到buffer中。最终,buffer的内容变为"Hello, Wor",并打印出来。