首页 > 解决方案 > 试图在 vsc 中使用 strcpy_s?

问题描述

当我尝试运行代码时,我得到:

warning: implicit declaration of function 'strcpy_s' [-Wimplicit-function-declaration]

我包括了 string.h 和 stdio.h。

代码:

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

int main(void) {
    static int foo = 0;
    char s[12];
    char *t = "01234567890123"
    printf("foo %p\n s %p\n", &foo, s);
    strcpy_s(s, 11, t);
}

标签: cstringvisual-studio-codestdiostrcpy

解决方案


strcpy_s()不能在没有以下情况下声明__STDC_WANT_LIB_EXT1__

#define __STDC_WANT_LIB_EXT1__
#include <string.h>

如果实现未定义__STDC_LIB_EXT1__,则扩展在您的库中不可用。

由于您没有检查errno_t来自的返回值strcpy_s,因此最好使用更广泛支持的strncpy().

strcpy_s()(甚至)的优点strncpy_s()是它们会告诉您何时失败,并且成功保证目的地为 NUL 终止。但是由于您没有检查错误,因此几乎没有优势。这可以通过明确确保s[11]为 NUL 来解决,例如:

零初始化:

char s[12] = {0} ;

或任务:

s[sizeof(s) - 1] = '\0' ;
#include <string.h>
#include <stdio.h>

int main(void) 
{
    static int foo = 0;
    char s[12] = {0} ;
    char *t = "01234567890123"
    printf("foo %p\n s %p\n", &foo, s);

    strncpy(s, t, sizeof(s) - 1) ) ;

    return 0 ;
}

请注意,在这种情况下strncpy()会将 11 个字符复制到s,并且不会写入 NUL 终止符。在这种情况下,我对整个数组进行了零初始化,但在目的地不知道为零初始化或长度变量的情况下,更安全的习惯用法是添加终止符:

strncpy(s, t, len ) ;
s[len] = '\0' ;

或者特别是在这个例子中:

strncpy(s, t, sizeof(s) - 1) ) ;
s[sizeof(s) - 1)] = '\0' ;

推荐阅读