【问题标题】:Print File name to stdout将文件名打印到标准输出
【发布时间】:2015-08-31 11:21:33
【问题描述】:

我想运行一个程序,并允许用户在同一行输入。我检查文件是否存在,如果不存在,打印

FILE : 没有这样的文件或目录

    FILE* filename;
    filename = fopen(argv[2], "wb");
        //validate file name
        if(!filename) {
            perror(filename);
            return EXIT_FAILURE;
        }

当我编译时,我收到以下警告:

预期为 âconst char *â 但参数类型为 âstruct FILE *â

【问题讨论】:

  • filename 的类型是什么? char *?
  • 我完全被这个问题的措辞弄糊涂了..
  • @EugeneSh。哈哈。耐心点,我的朋友……让 OP 添加更多信息……
  • 好吧,我想我们应该提供一点帮助。 perror 用于由标准错误编号给出的打印错误。与用户输入的文件名无关。
  • @EugeneSh。这有助于解释吗?打印的“文件”部分应该是文件名>我不确定如何打印出文件名。我可以使用 printf(),但使用 %p 不起作用。

标签: c file error-handling


【解决方案1】:

在上面的代码中,filenameFILE *,而不是带有文件名的字符串。由于argv[2] 似乎是文件名,您可以尝试:

        if(!filename) {
            perror(argv[2]);
            return EXIT_FAILURE;
        }

...但您应该首先检查是否设置了argv[2](即argc > 2)。

【讨论】:

    【解决方案2】:

    代码需要打印文件的名称,而不是具有NULL 值的FILE *

    不经过额外检查就打印一个打开有困难的文件的名称是不明智的。用引号或其他东西打印名称也很好,以帮助区分麻烦文件名的开头和结尾。

    OP 的原始“文件名”是文件变量名称的弱选择,因为该变量不是文件的名称。建议像“output_file”这样的东西。 argv[2] 是文件名。

    const char *filename = argv[2];
    FILE* output_file;
    
    output_file = fopen(filename, "wb");
    //validate file pointer
    if(!output_file) {
       perror("Unable to open file for writing.");
       if (argc > 2 && filename) {
         fprintf(stderr, "\"%s\"\n", filename);
       }
       return EXIT_FAILURE;
    }
    

    【讨论】:

      【解决方案3】:
         FILE* filename;
          filename = fopen(argv[2], "wb");
              //validate file name
              if(!filename) {
                  fprintf(STDERR,"%s", filename);
                  perror(" files to open: ");
              }
      

      perror 打印错误消息,后跟最后一个错误的字符串表示;

      【讨论】:

      • any 字符串直接交给fprintf 是不是一个潜在的安全漏洞?
      【解决方案4】:

      在这一行:

      perror(filename);
      

      指的是指向文件描述符的指针 不是指向 char 字符串的指针。

      建议使用:

      perror(argv[2]);
      

      顺便说一句:perror() 输出到标准错误,而不是标准输出

      【讨论】: