为什么我不能使用动态分配的字符串创建临时文件?
Why can I not create a temporary file using a dynamically allocated string?
我正在尝试创建一个包含 mkstemp
日志条目的目录。但是,据我所知,我不能将字符串常量传递给 mkstemp
。我为字符串分配内存并使用 snprintf
格式化我认为可以工作的输出,但是 mkstemp
returns 一个负值设置 errno 为 EINVAL。
但是,在 linux manual for mkstemp
中,它明确表示:
EINVAL For mkstemp() and mkostemp(): The last six characters of
template were not XXXXXX; now template is unchanged.
此外 mkstemp
从不修改我的动态字符串。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LOG_DIR "/tmp"
int main(int argc, char **argv) {
char *fname;
FILE *fp;
if(argc != 3) {
fprintf(stderr, "Usage: %s <msg> <severity>\n", argv[0]);
return 0;
}
int length = snprintf(NULL, 0, "%s/log_entry.XXXXXX", LOG_DIR); // snprintf returns the required length for my string
if(length < 0) {
perror("snprintf failed");
return 1;
}
fname = malloc(sizeof(char) * length); // allocate memory for fname based on the return value of snprintf
snprintf(fname, length, "%s/log_entry.XXXXXX", LOG_DIR); // send formatted output into fname
int fd = mkstemp(fname); // this returns -1 and errno is set to 22
if(fd < 0) {
perror("failed to create entry file");
return 1;
}
fp = fdopen(fd, "w");
if(fp == NULL) {
perror("failed to open entry file");
return 1;
}
fprintf(fp, "\"%s\" %d ",argv[1], atoi(argv[2]));
fflush(fp);
fclose(fp);
free(fname);
return 0;
}
这段代码在我的两台 Linux 机器上都出现错误,但是如果我删除动态分配的字符串并显式设置 fname
它会起作用
char fname[] = "/tmp/log_entry.XXXXXX";
fname = malloc(sizeof(char) * length);
你把它填满,'[=12=]'
不留space。 :eave a space for null terminator -
fname = malloc(sizeof(char) *(length+1));
然后将 snprintf
中的长度也增加到 length+1
.
fname = malloc(sizeof(char) * length);
应该是:
fname = malloc(sizeof(char) * (length + 1));
现在
snprintf(fname, length+1, "%s/log_entry.XXXXXX", LOG_DIR);
将创建文件名。在您的版本中,文件名未以 6 个“X”结尾,这导致 mkstemp
失败。
我正在尝试创建一个包含 mkstemp
日志条目的目录。但是,据我所知,我不能将字符串常量传递给 mkstemp
。我为字符串分配内存并使用 snprintf
格式化我认为可以工作的输出,但是 mkstemp
returns 一个负值设置 errno 为 EINVAL。
但是,在 linux manual for mkstemp
中,它明确表示:
EINVAL For mkstemp() and mkostemp(): The last six characters of template were not XXXXXX; now template is unchanged.
此外 mkstemp
从不修改我的动态字符串。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LOG_DIR "/tmp"
int main(int argc, char **argv) {
char *fname;
FILE *fp;
if(argc != 3) {
fprintf(stderr, "Usage: %s <msg> <severity>\n", argv[0]);
return 0;
}
int length = snprintf(NULL, 0, "%s/log_entry.XXXXXX", LOG_DIR); // snprintf returns the required length for my string
if(length < 0) {
perror("snprintf failed");
return 1;
}
fname = malloc(sizeof(char) * length); // allocate memory for fname based on the return value of snprintf
snprintf(fname, length, "%s/log_entry.XXXXXX", LOG_DIR); // send formatted output into fname
int fd = mkstemp(fname); // this returns -1 and errno is set to 22
if(fd < 0) {
perror("failed to create entry file");
return 1;
}
fp = fdopen(fd, "w");
if(fp == NULL) {
perror("failed to open entry file");
return 1;
}
fprintf(fp, "\"%s\" %d ",argv[1], atoi(argv[2]));
fflush(fp);
fclose(fp);
free(fname);
return 0;
}
这段代码在我的两台 Linux 机器上都出现错误,但是如果我删除动态分配的字符串并显式设置 fname
它会起作用
char fname[] = "/tmp/log_entry.XXXXXX";
fname = malloc(sizeof(char) * length);
你把它填满,'[=12=]'
不留space。 :eave a space for null terminator -
fname = malloc(sizeof(char) *(length+1));
然后将 snprintf
中的长度也增加到 length+1
.
fname = malloc(sizeof(char) * length);
应该是:
fname = malloc(sizeof(char) * (length + 1));
现在
snprintf(fname, length+1, "%s/log_entry.XXXXXX", LOG_DIR);
将创建文件名。在您的版本中,文件名未以 6 个“X”结尾,这导致 mkstemp
失败。