关于使用Visio Studio 2022版本中strcpy()函数报错问题

 学习函数时,学到了strcpy()函数,本来打算练习一番,没想到出现了一系列的错误。

首先介绍一下strcpy()函数:

strcpy()函数是C语言中的一个字符串函数,用于将一个字符串复制到另一个字符串中。它的原型如下:

char *strcpy(char *dest, const char *src);

函数接受两个参数,destsrc,分别表示目标字符串和源字符串。dest应该是一个足够大的字符数组,以容纳复制的字符串,而src是要复制的字符串。

函数的作用是将src指向的字符串复制到dest指向的字符串中,包括字符串的终止符\0。复制完成后,dest将包含完整的src内容。

需要注意的是,函数的返回值是一个指向目标字符串的指针。这意味着可以将strcpy()的返回值直接赋给另一个字符指针变量。

使用strcpy()函数时,需要确保目标字符串dest有足够的空间来存储源字符串src的内容,以防止缓冲区溢出。

然后我就用写了一个简单的代码,如下:

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

int main()
 {
    char source[] = "Hello";
    char destination[5];

    strncpy(destination, source);

    printf("%s\n", destination);
    return 0;
}

 运行报错,如下所示:

 然后右击strncpy点击“转到定义”可以看到:

 这里看不太懂,于是我改用strncpy_s(destination, source);

结果同样会报错,如下:

于是,右击strncpy_s转到函数定义,显示如下:

 发现与刚才的strcpy()函数定义不太相同,strncpy_s()函数需要4个参数,所以错误中显示“用于调用的参数太少”,经过查找,发现4个参数的含义如下:

  • _Destination:指向目标缓冲区的指针。这个缓冲区将用于存储源字符串的副本。

    • _Out_writes_z_(_SizeInBytes):表示这是一个输出参数,用于指定目标缓冲区的大小(以字节为单位),并告诉静态分析工具检查缓冲区是否足够大。
  • _SizeInBytes:目标缓冲区的大小(以字节为单位)。

    • _In_:表示这是一个输入参数,用于指定目标缓冲区的大小。
  • _Source:指向源字符串的指针,用于复制到目标缓冲区。

    • _In_reads_or_z_(_MaxCount):表示这是一个输入参数,用于指定源字符串的大小(以字符为单位),并告诉静态分析工具检查源字符串是否足够大。
  • _MaxCount:要复制的最大字符数。

    • _In_:表示这是一个输入参数,用于指定要复制的最大字符数。
  • 返回值:表示函数的执行状态。

    • errno_t:这是一个代表错误码的类型。如果函数执行成功,则返回0。否则,返回一个非零错误码。

strncpy_s()函数的作用是将源字符串的指定个数字符复制到目标字符串中,同时可以指定目标字符串和源字符串的大小。该函数的返回值为errno_t类型,用于指示操作成功与否。

于是,我修改上述代码,如下所示:

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

int main()
{
    char source[10] = "Hello";
    char destination[5];

    strncpy_s(destination, sizeof(destination), source, sizeof(source));

    printf("%s\n", destination);
    return 0;
}

 结果报错,如下所示:

  

 重新修改代码,改为strncpy_s(destination, sizeof(destination), source, sizeof(destination));

运行仍然报错,与上面的错误提示一样。 

该错误是由于调用strcpy_s函数时,目标缓冲区大小不足导致的

解决方法有两种:

  1. 调整目标缓冲区的大小:将destination数组的大小增加到能够容纳源字符串的大小。例如,将char destination[5]修改为char destination[10]

  2. 使用更安全的字符串函数:除了strcpy_s函数,C语言中还有其他一些更安全的字符串函数,如strncpy_sstrncpy_s函数可以指定要复制的最大字符数,以避免目标缓冲区溢出的问题。

如果不修改大小,就只能减少目标缓冲区的大小,如下所示,运行不会报错,但缺点是字符串复制不全

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

int main() {
    char source[10] = "Hello";
    char destination[5];

    // 使用strncpy_s向destination复制source
    // 目标缓冲区大小为5,复制的最大字符数为4
    strncpy_s(destination, sizeof(destination), source, sizeof(destination) - 1);
    printf("%s\n", destination);
    return 0;
}

 结果如下所示:

 后来我想明白,为什么目标缓冲区的大小会不足,明明“Hello”只有5个字符。原因在于字符串的写入后面会隐藏一个字符‘\0’,这在我的另一篇文章讲解过:关于循环语句练习二-CSDN博客。所以source中存的是6个字符,所以会报错。

修改代码,如下所示:

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

int main() {
    char source[] = "Hello";
    char destination[10];

    
    strncpy_s(destination, sizeof(destination), source, sizeof(destination) );
    printf("destination = %s\n", destination);
    printf("sizeof(source) = %d\n", sizeof(source));
    return 0;
}

运行结果如下所示,我们也可以看到数组source 的大小确实是6.

至此, 函数strncpy_s()学习完毕!

  • 29
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值