Как я могу найти ошибку при открытии файла? - PullRequest
0 голосов
/ 02 февраля 2011

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 ]

1 голос
/ 02 февраля 2011

Вы, конечно, должны попробовать что-то из perror, как указано в предыдущем комментарии, но после просмотра вашего кода я думаю, что вам следует проверить режимы, в которых файлы открываются еще раз.

Чтобы открыть файл в режиме "r", сначала должен существовать файл, иначе fopen выдаст ошибку.Вы не указали, где вы сталкиваетесь с ошибкой в ​​fopen, но всегда лучше проверять возвращаемые значения всех файловых операций, а также операций выделения памяти.

Ниже приведен немного глупый способ проверить возвращаемое значение (пропуская дополнительную переменную часть):

FILE * fp = NULL;

if ((fp = fopen (test.txt, "r")) == NULL) {printf ("ошибка fopen");return FALSE // - 1 или что вы хотите вернуть в случае неудачи;}

else {// ваш код}

1 голос
/ 02 февраля 2011

Вы должны поместить perror в Fopen и Fclose, чтобы описать, почему завернутая функция завершилась неудачей.

Справочная страница Linux для fopen утверждает, что может произойти сбой по следующим причинам:

  • при условии, что режим недействителен

  • если функция malloc, вызываемая в fopen, не работает

  • , если не работает функция open, используемая в fopen.

0 голосов
/ 02 февраля 2011

Вы можете использовать perror(), если вы не против работать в рамках ограничений его форматирования, или вы можете сделать эквивалент:

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

Вы должны смотреть только на errnoпосле того, как функция сообщила о сбое.Он также может быть установлен после успешной функции.Например, в Solaris, если вывод не является 'tty', вы часто найдете ENOTTY в errno после успешной операции печати - потому что он проверял, был ли дескриптор выходного файла 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() является примечанием (не завершается) и включает информацию об ошибке системы - errno и strerror(errno).Если бы я вместо этого позвонил err_syserr(), это завершило бы программу, а err_remark() не включало бы информацию из errno, и ни один не err_error().Я нахожу краткость, обеспеченную функциями, полезной.Все функции автоматически включают имя программы в начале сообщения;Вы можете настроить его так, чтобы он включал метки времени, PID или другую информацию.Вы используете err_setarg0(argv[0]); в main(), чтобы установить имя программы;Вы можете, конечно, изменить его в любое время.

...