【问题标题】:Enter custom file name to be read?输入要读取的自定义文件名?
【发布时间】:2010-05-08 19:45:40
【问题描述】:

我希望允许用户键入要读取/写入的任何 .txt 文件的名称。

这是我的代码:

  printf("Enter .txt file name\n");
  scanf("%s",&fname);
  FILE *inputf;
  inputf=fopen(&fname,"w");

问题是这个方法不起作用(有 &fname)作为参数。

我可以想象它,因为 C 需要“filename.txt”才能工作......即使我输入例如:“custom.txt”,程序也会返回错误“存储块不足以执行此操作”

实现此目的的正确方法是什么?

我使用 C 并且我几乎使用基本命令..(不太高级)

非常感谢!!!

【问题讨论】:

  • 你如何定义(和初始化)fname

标签: c file file-io


【解决方案1】:

scanf 语句将尝试将作为输入输入的文件名存储到内存中,从作为其第二个参数传递的地址开始。所以你必须分配/保留一些内存并将其地址传递给scanf。

由于你没有提到fname的类型,让我列出可能性然后回答你。

  1. char fname;

scanf 的第 2 个参数和 fopen 的第 1 个参数,都需要是 char *。因此,fname 或 &fname 的传递地址是有效的。但它有一个问题。

当您声明 'char fname' 时,您只保留了 1 个字符的内存。当 scanf 尝试存储输入文件名时,它必须写入超过 1 个字符。所以最终你会覆盖一些其他的内存。

  1. char *fname;

在这种情况下,将 fname 传递给 scanf 和 fopen,而不是 '&fname'。 但是在使用 fname 之前,您必须分配一些内存(例如使用 malloc)。否则 fname 会包含一些垃圾地址,scanf 会尝试覆盖一些随机内存。

因此,要么将 fname 声明为 char fname[N] 或 char *fname = malloc(N+1);(其中 N 是您要输入的文件名的最大可能长度)。

然后,将 fname 传递给 scanf 和 fopen,如下所示:

scanf("%s",fname);

inputf = fopen(fname,"w");

【讨论】:

  • 唉,信息量不够。如果你用malloc 保留内存,你最终也必须free 它,否则你会得到内存泄漏。因此建议尽可能使用堆栈变量(在本例中为char[])。
  • 感谢您提供的额外信息 :)
【解决方案2】:

fname 定义为一个字符数组,并假设您希望文件名(不带扩展名)作为输入(这意味着您需要将扩展​​名附加到它):

char fname[128];
printf("Enter .txt file name\n");
scanf("%123s",fname);
strcat(fname,".txt");
FILE *inputf;
inputf=fopen(fname,"w");

请注意,添加了输入长度检查以避免scanf 中的缓冲区溢出错误。

【讨论】:

  • 非常感谢!!!您向我展示了我需要将其设为数组,以及如何在每个文件名后添加 .txt .. 谢谢,内容丰富,正是我想要的。
  • 有点迂腐:如果用户输入 124 个或更多字符,它仍然容易受到缓冲区溢出的影响,因为空终止符没有足够的空间。你可能想要scanf("%123s",fname);
  • 谢谢Peter,我使用了你提到的strcat方法:)
【解决方案3】:

试试inputf = fopen(fname,"w");

【讨论】:

    【解决方案4】:

    我认为这会有所帮助

    #include <stdio.h>
    
    void read_name(char *);
    
    int main(void)
                   {
                     char name[BUFSIZ];
                     char line[BUFSIZ];
                     FILE *f;
                     printf("Name ");
                     read_name(name);
                     if ( (f=fopen(name,"r"))==NULL)
                     return -1;
                     else
                     return 0;
                     fclose(f);
                   }     
    void read_name(char *s)
                   {
                     int i;
                     fgets(s,BUFSIZ,stdin);
                     for (i=0; s[i]!='\n'; i++);
                     s[i]='\0';
                     return;
                    }
    

    【讨论】:

    • 欢迎来到 StackOverflow,请阅读 How to Answer 并学习如何写出好的答案。
    【解决方案5】:

    另外,如果你只想读取一个文件名,你可以做sscanf(file,"%s",t),它会将文件名存储到t

    【讨论】:

      猜你喜欢
      • 2011-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-10
      相关资源
      最近更新 更多