通过 snprintf 打开
fopen through snprintf
我在编译我的程序时遇到问题,但在尝试将 strcpy
和 strcat
压缩为 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");
我可以打开文件,但只有当我使用 strcpy
和 strcat
时才可以打开文件 - 这正是我想要摆脱的。
所以您的代码存在一些问题,所有评论都证明了这一点。
现在我们将跳过 fopen
and focus on the snprintf
。 snprintf
就像 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.h
和 errno.h
才能正常工作)
我在编译我的程序时遇到问题,但在尝试将 strcpy
和 strcat
压缩为 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");
我可以打开文件,但只有当我使用 strcpy
和 strcat
时才可以打开文件 - 这正是我想要摆脱的。
所以您的代码存在一些问题,所有评论都证明了这一点。
现在我们将跳过 fopen
and focus on the snprintf
。 snprintf
就像 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.h
和 errno.h
才能正常工作)