在C中使用带有输入文件名的fopen

在C中使用带有输入文件名的fopen,c,string,file,fopen,C,String,File,Fopen,在我的代码中的某个时刻,我想为我将要创建(和/或编辑)的文件读取一个名称,我得出以下结论: FILE *fp; char filename[15]; fgets(filename, 15, stdin); fp = fopen(filename, "a"); fprintf(fp, "some stuff goes here"); fclose(fp); 即使它编译并运行,它也不会创建(或打开,如果我手动创建的话)由filename指定的文件 您的建议是什么?您需要声明文件名[16]为了能够使

在我的代码中的某个时刻,我想为我将要创建(和/或编辑)的文件读取一个名称,我得出以下结论:

FILE *fp;
char filename[15];
fgets(filename, 15, stdin);
fp = fopen(filename, "a");
fprintf(fp, "some stuff goes here");
fclose(fp);
即使它编译并运行,它也不会创建(或打开,如果我手动创建的话)由
filename
指定的文件

您的建议是什么?

您需要声明
文件名[16]
为了能够使用15个字符,您需要为终止零留出空间。

在读取一行输入后存储从
stdin
读取的换行符。您需要手动将其剥离,例如

size_t len = strlen(filename);
if (len > 0 && filename[len - 1] == '\n')
    filename[len - 1] = '\0';
您还应该检查
fopen()
是否未返回
NULL
,如果无法打开文件,它将执行此操作。我认为将
fprintf
NULL
文件指针一起使用是未定义的行为。

通常(但不总是),
fgets()
会给您额外的
'\n'
追加输入的字符串,因为

换行符使FGET停止读取,但它被视为 函数指定的有效字符,并包含在复制到的字符串中 str

参考:

要使用最少的代码消除该
'\n'
,请执行以下操作:

fgets(filename, 15, stdin);
filename[strcspn(filename, "\n")] = '\0';

由于fgets将从EOF或换行符中读取字符串,并且如果读取了换行符,则将其存储到缓冲区中。这意味着您必须手动修剪结束的换行符(如果有)。我建议改用fscanf,它不会将换行添加到缓冲区:

char filename[15];
int ret = fscanf(stdin, "%s", filename);
if (ret != 1) { // handle input error }
fp = fopen(filename, "a");

您确定要在正确的位置查找文件吗。在打开fp==NULL之后,还要执行一项检查,查看它是否为空。如果为空,则表示打开时出错。使用perror函数获取错误消息。可能重复的错误消息不会将换行读入缓冲区,但不会处理带空格的文件名。