strcat_s的以下用法显示“C4047:间接级别不同”

时间:2016-11-19 08:12:55

标签: c strcat-s

以下几行出了什么问题?

//Thanks to Mark
#include <string.h>
#include <stdio.h>
int main(int argc, char* argv[])
{
char datfile[127];
if(argc < 2) return -1;
strcpy_s(datfile, strlen(argv[1]), argv[1]);
strcat_s(datfile, strlen(argv[1]) + 4, ".dat");
printf("%s\n",datfile);//the warning appears here (why?)
return 0;
}

显示Warning C4047 'function': 'const char *' differs in levels of indirection from 'char'

我已经浏览了MSDN为C4047提供的文档。它命名一个名为levels of indirection的术语。我已经在网络上讨论了与此主题i.e. levels of indirection相关的一些讨论,并且(作为新手)我发现了超出我的范围的那些讨论。

如果有人用上面的代码指出问题,我会很高兴,并提供一个简单易懂的术语level of indirection的解释。

1 个答案:

答案 0 :(得分:1)

原始错误的可验证示例:

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

int main(int argc, char* argv[])
{
    char datfile[127];
    if(argc < 2)
        return -1;
    strcpy_s(datfile, strlen(argv[1]), argv[1]);
    strcat_s(datfile, strlen(argv[1]) + 4, '.dat');
    printf("%s\n",datfile);
    return 0;
}

VS2015的输出(cl / nologo / W4 test.c):

test.c
test.c(10): warning C4047: 'function': 'const char *' differs in levels of indirection from 'int'
test.c(10): warning C4024: 'strcat_s': different types for formal and actual parameter 3

“间接级别”表示指针级别不匹配。 int, int*, int**具有不同的间接层次。

对于@Mat建议,以下行改为双引号:

strcat_s(datfile, strlen(argv[1]) + 4, ".dat");

编译没有警告但由于参数使用不正确而崩溃。 strcpy_sstrcat_s的第二个参数是目标缓冲区的长度,而不是源字符串长度。由于strlen(arg[v])不包含nul终止符,strcpy_s将失败,因为它将尝试复制比指示的字节多一个字节。

正确使用第二个参数:

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

int main(int argc, char* argv[])
{
    char datfile[127];
    if(argc < 2)
        return -1;
    strcpy_s(datfile, sizeof datfile, argv[1]);
    strcat_s(datfile, sizeof datfile, ".dat");
    printf("%s\n",datfile);
    return 0;
}

输出:

C:\>cl /nologo /W4 test.c
test.c

C:\>test abc
abc.dat