通过 snprintf 打开

fopen through snprintf

我在编译我的程序时遇到问题,但在尝试将 strcpystrcat 压缩为 snprintf 时(以删除不必要的代码行),否则可以正常工作,编译警告

passing argument 2 of ‘snprintf’ makes integer from pointer without a cast

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

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");

我可以打开文件,但只有当我使用 strcpystrcat 时才可以打开文件 - 这正是我想要摆脱的。

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

现在我们将跳过 fopen and focus on the snprintfsnprintf 就像 printf 一样,除了您需要首先传递两个额外的参数,一个 char * 指示存储渲染字符数据的位置,以及一个 size_t 指示char * 有多少 space 可用。执行此操作的惯用方法(假设 char[] 是目的地)是像这样使用 sizeof()

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

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

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

最后,因为 snprintf 的 return 值是一个 int,你不能将它作为第一个参数传递给 fopen,因为它需要第一个参数为 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 的第一个参数是指向动态分配内存的指针(即来自 malloc),您将无法使用 sizeof() 和相反,需要显式传递动态分配区域的大小。 sizeof() 在编译时计算(忽略 VLAs),而不是在运行时计算。

(如果要使用 strerror() 调用,则需要 #include string.herrno.h 才能正常工作)