我怎么能从打开文件中找到错误?

时间:2011-02-02 00:59:22

标签: c fopen

Fopen和Fclose是我的源文件中的包装函数,用于在打开文件时检查错误。当我运行我的程序时,它说有一个Fopen错误。我认为没有理由在文件打开期间出错。

很抱歉长代码。

#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include "perry.h"

int main(void)
{
    void copyStrings(char *infile, char *outfile, char ch);
    void compareFiles(char *infile, char *outfile);

    char inputfile[80];
    char outputfile[80];
    char ch;

    printf("Enter input filename: ");
    scanf("%s", inputfile);
    printf("Enter output filename: ");
    scanf("%s", outputfile);
    printf("Enter a character: ");
    scanf(" %c", &ch);

    if(!isalpha(ch))
    {
        printf("Did not enter a letter!");
        exit(1);
    }

    copyStrings(inputfile, outputfile, ch);
    compareFiles(inputfile, outputfile);

    return 0;
}

void copyStrings(char *infile, char *outfile, char ch)
{
     int count;
     char *ptr;
     char *line;
     char linePart[80];
     FILE *fin;
     FILE *fout;

     fin = Fopen(infile, "r");
     fout = Fopen(outfile, "w");

     while(fgets(line, 80, fin) != NULL)
     {
         for(ptr=line;ptr<line+strlen(line);ptr++)
         {     
               if(*ptr == ch)
                       count ++;
         }
         if(count < 2)
             fputs(line, fout);
         else
         {   
             memset(linePart, '\0', strlen(line)+1);
             line = strchr(line, ch);
             strncpy(linePart, line, strchr(line+1, ch) - line + 1);
             fputs(linePart, fout);
             fprintf(fout, "\n");
         }
     }

     Fclose(fout);
     Fclose(fin);

     return;
}   

void compareFiles(char *infile, char *outfile)
{
     int count = 0;
     char inputString[80];
     char outputString[80];
     FILE *fin;
     FILE *fout;

     fin = Fopen(infile, "r");
     fout = Fopen(outfile, "r");

     while(fgets(inputString, 80, fin) != NULL)
     {
         count += 1;
         if(strcmp(inputString, fgets(outputString, 80, fout)) == 0)
         {
             printf("Strings are equal at line %d\n\nBoth strings look like this: %s",
             count, inputString);
         }
     }
     Fclose(fout);
     Fclose(fin);

     return;
}

3 个答案:

答案 0 :(得分:1)

您应该在perrorFopen中添加Fclose,以便它描述包装函数失败的原因。

fopen的Linux手册页指出它可能因以下原因而失败:

  • 提供的模式无效

  • 如果在malloc内调用的fopen函数失败

  • 如果open中使用的fopen功能失败。

答案 1 :(得分:1)

你当然应该尝试前面评论中指出的perror事情,但在查看你的代码之后我认为你应该再次检查文件被打开的模式。

要以“r”模式打开文件,必须先存在,否则fopen将返回错误。您还没有指出您在fopen中遇到故障的位置,但最好检查所有文件操作的返回值以及内存分配操作。

以下是检查返回值(跳过额外变量部分)有点俗气的方法:

FILE * fp = NULL;

if((fp = fopen(test.txt,“r”))== NULL) {     printf(“fopen failed”);     返回FALSE // - 1或任何你想要返回的失败案例; }

否则 {     //你的代码 }

答案 2 :(得分:0)

如果你不介意在格式化的限制范围内工作,你可以使用perror(),或者你可以做相同的事情:

fprintf(stderr, "Failed to open %s (%d: %s)\n", filename, errno, strerror(errno));

在功能报告失败后,您应该只查看errno。它也可以在成功的函数之后设置。例如,在Solaris上,如果输出不是'tty',则在成功打印操作后,您将经常在errno中找到ENOTTY - 因为它检查输出文件描述符是否为tty且实际上不是。但功能成功了。

如果代码中的函数调用多于我所显示的行,最好在早期保留errno - 因为它被其他函数篡改(全局的许多缺点之一)变量)。所以,我经常写:

{
    int errnum = errno;
    ...any other processing...
    fprintf(stderr, "%s: failed to open %s for reading (%d: %s)\n",
            prog_name, file_name, errnum, strerror(errnum));
}

好吧,我写的逻辑相当于那个;我有一个报告错误的库,所以我实际上写了:

err_sysrem("failed to open %s for reading", file_name);

包中的所有功能都从err_开始。函数err_sysrem()是备注(不退出)并包含系统错误信息 - errnostrerror(errno)。如果我改为呼叫err_syserr(),它将终止该计划,err_remark()将不包含来自errno的信息,err_error()也不会。我发现功能提供的简洁有益。这些功能都自动包含消息开头的程序名称;您可以将其配置为包括时间戳或PID或其他信息。您可以在err_setarg0(argv[0]);中使用main()来设置程序名称;当然,你可以随时改变它。