【问题标题】:fopen through snprintf通过 snprintf 打开
【发布时间】:2019-03-27 14:14:49
【问题描述】:

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

传递“snprintf”的参数 2 从指针生成整数而无需强制转换

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

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

event->name 是文件名(及其扩展名),例如图片1.jpg。

hashDirectory"/home/user/Documents/_Hash"

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

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

【问题讨论】:

  • 将太多代码塞进一行的一个非常非常糟糕的副作用是在它不起作用时无法调试它......
  • 那是因为第二个参数是size_t 而不是字符串。在此处查看函数的文档cplusplus.com/reference/cstdio/snprintf 并相应地修复您的函数调用。
  • @Blaze ...因为snprintf 返回int,而fopen 接受const char * 作为其第一个参数。
  • 您要创建什么文件名?您有一个包含扩展名的文件名,并在其中添加 ": .txt"
  • @Gerhardh 只是一个 .txt 文件,但删除原始文件扩展名是另一个问题哈哈。

标签: c file printf fopen


【解决方案1】:

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

现在我们将跳过fopen 并专注于snprintfsnprintfprintf 一样,除了你需要首先传递两个额外的参数,一个 char * 指示在哪里存储渲染的字符数据,一个 size_t 指示在 @ 有多少可用空间987654330@。执行此操作的惯用方法(假设 char[] 是目标)是像这样使用 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 的返回值是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),而不是在运行时。

(如果您想使用该部分,您需要 #include string.herrno.h 调用 strerror() 才能工作)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-20
    相关资源
    最近更新 更多