首页 > 解决方案 > 通过 snprintf 打开

问题描述

我在编译我的程序时遇到问题,但是,在编译警告时,在尝试压缩strcpy&strcatsnprintf(以删除不必要的代码行)

传递 'snprintf' 的参数 2 从没有强制转换的指针生成整数

呈现自己。我试过四处寻找有这个问题的其他人,但是一旦调整他们的解决方案似乎不适用于我的代码

fileDir在程序开始时定义为:char fileDir[1000];

event->name是文件的名称(及其扩展名),例如picture1.jpg。

hashDirectory"/home/user/Documents/_Hash"

FILE *ftest2=fopen(snprintf(fileDir, "%s: %s: %s", hashDirectory, event->name, ".txt"), "wt");

我可以打开文件,但是只有当我使用strcpyand strcat- 这是我想要摆脱的。

标签: cfileprintffopen

解决方案


因此,所有评论都证明了您的代码存在一些问题。

现在我们将跳过fopen并专注于snprintf. snprintf就像printf除了你需要首先传递两个额外的参数,一个char *指示在哪里存储渲染的字符数据,一个size_t指示在char *. 这样做的惯用方法(假设 achar[]是目的地)是这样使用sizeof()的:

int res = snprintf(fileDir, sizeof(fileDir), /* Other arguments omitted */);

snprintf返回打印的字符数(作为int)。如果该数字大于或等于,sizeof(fileDir)则其中的任何内容都fileDir将被截断(但将始终被NULL终止)。

if (res >= sizeof(fileDir)) {
    /* fileDir contains an incomplete path, handle this as an error */
}

最后,因为的返回值snprintf是 a int,所以你不能将它作为第一个参数传递给,fopen因为它期望第一个参数是 a const char *。所以这些需要是单独的步骤。

说了这么多,您构建路径的方式似乎也不正确。在下面的完整示例中,我已修复它:

FILE *ftest2;

int res = snprintf(fileDir, sizeof(fileDir), "%s/%s.txt", hashDirectory, event->name);
if (res >= sizeof(fileDir)) {
    fprintf(stderr, "The pathname was truncated. Cannot proceed.\n");
    return -1;
}

ftest2 = fopen(fileDir, "wt");
if (!ftest2) {
    fprintf(stderr, "Failed to open `%s': %s\n", fileDir, strerror(errno));
    return -1;
}

/* Rest of your code */

重要说明,如果第一个参数snprintf是指向动态分配内存的指针(即 from malloc),您将无法使用sizeof(),而是需要显式传递动态分配区域的大小。sizeof()在编译时评估(忽略VLA),而不是在运行时。

(如果你想使用那部分,你需要调用才能#include string.h工作errno.hstrerror()


推荐阅读