Открытие файла в C через процесс - PullRequest
0 голосов
/ 28 ноября 2010

Я пытаюсь создать программу, которая выполняет следующие действия:

  1. Откройте файл и прочитайте одну строку.

  2. Откройте другуюфайл и прочитайте другую строку.

  3. Сравните две строки и напечатайте сообщение.

Это мой код:

#include <stdio.h>
#include <string.h>
int findWord(char sizeLineInput2[512]);

int main()
{
    FILE*cfPtr2,*cfPtr1;
int i;
    char sizeLineInput1[512],sizeLineInput2[512];
    cfPtr2=fopen("mike2.txt","r");
    // I open the first file
while (fgets(sizeLineInput2, 512, cfPtr2)!=NULL)
   // I read from the first 1 file one line 
{
 if (sizeLineInput2[strlen(sizeLineInput2)-1]=='\n')
            sizeLineInput2[strlen(sizeLineInput2)-1]='\0';
             printf("%s \n",sizeLineInput2);
             i=findWord(sizeLineInput2);

   //I call the procedure that compares the two lines

}
getchar();
    return 0;
}
int  findWord(char sizeLineInput2[512])
{
int x;
char sizeLineInput1[512];
File *cfPtr1;
cfPtr1=fopen("mike1.txt","r");

// here I open the second file

     while (fgets(sizeLineInput1, 512,cfPtr1)!=NULL)
     {
        if (sizeLineInput1[strlen(sizeLineInput1)-1]=='\n')
            sizeLineInput1[strlen(sizeLineInput1)-1]='\0';
        if (strcmp(sizeLineInput1,sizeLineInput2)==0)

//Here, I compare the two lines

        printf("the words %s and %s are equal!\n",sizeLineInput1,sizeLineInput2);
        else
        printf("the words %s and %s are not equal!\n",sizeLineInput1,sizeLineInput2);
        }
    fclose(cfPtr1);
    return 0;
}

Кажется, есть некоторые проблемы с обработкой файловых указателей.Может ли кто-нибудь проверить это и сказать мне, какие исправления я должен сделать?

Ответы [ 2 ]

2 голосов
/ 28 ноября 2010

Деконструкция и реконструкция

Текущая структура кода, чтобы быть вежливой, капризная.

Вы должны открывать файлы в той же функции - вероятно, main().Там должно быть два параллельных блока кода.Фактически, в идеале, вы должны выполнять открытие и обработку ошибок в функции, чтобы main() просто содержал:

FILE *cfPtr1 = file_open("mike1.txt");
FILE *cfPtr2 = file_open("mike2.txt");

Если элемент управления возвращается к main(), файлы открыты и готовы к использованию..

Затем вам нужно прочитать строку из каждого файла - снова в main().Если какой-либо файл не содержит строки, вы можете выручить с соответствующей ошибкой:

if (fgets(buffer1, sizeof(buffer1), cfPtr1) == 0)
    ...error: failed to read file1...
if (fgets(buffer2, sizeof(buffer2), cfPtr2) == 0)
    ...error: failed to read file2...

Затем вы вызываете код сравнения с двумя строками:

findWord(buffer1, buffer2);

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

Вы можете решитьтакже обернуть вызов fgets() и обработку ошибок в функции:

const char *file1 = "mike1.txt";
const char *file2 = "mike2.txt";

read_line(cfPtr1, file1, buffer1, sizeof(buffer1));
read_line(cfPtr2, file2, buffer2, sizeof(buffer2));

Эта функция может обрезать перевод строки с конца строки и обрабатывать все, что вы хотите, чтобы она выполнялась -и сообщите точную ошибку, включая имя файла, если что-то пойдет не так.Очевидно, что с переменными 'file1' и 'file2' вы будете использовать их вместо литеральных строк в вызовах file_open().Также обратите внимание, что преобразование их в переменные означает, что брать имена файлов из командной строки тривиально;вы просто устанавливаете 'file1' и 'file2', чтобы они указывали на список аргументов вместо аппаратных настроек по умолчанию.(Я на самом деле написал: const char file1[] = "mike1.txt"; кратко - но потом понял, что если вы обрабатываете имена файлов через командную строку, то вам нужны указатели, а не массивы.)

Кроме того, если вы открываете файл, вы должнызакройте файл тоже.Конечно, если ваша программа завершается, o / s убираются позади вас, но это хорошая дисциплина, в которую нужно войти.Одна из причин заключается в том, что не каждая программа завершает работу (вспомните о демонах, запускающих службы на вашем компьютере).Другое - то, что вы довольно часто кратко используете ресурс (файл, в текущем обсуждении) и больше не нуждаетесь в нем.Вы не должны хранить ресурсы в вашей программе дольше, чем вам нужно.

Философия

У Поли в его книге 1957 года "Как ее решить" есть изречение:

  • Старайтесь симметрично трактовать то, что симметрично, и не разрушайте бессмысленно любую естественную симметрию.

Это такой же верный совет в программировании, как и в математике.И в своей классической книге 1978 года «Элементы стиля программирования» Керниган и Плаугер делают выразительные утверждения:

  • [вызов] подпрограммы позволяет нам обобщить неровностей всписок аргументов [...]
  • Сама подпрограмма суммирует закономерности кода.

В более современных книгах, таких как ' The PragmaticПрограммист 'от Hunt & Thomas (1999), изречение переведено на быстрый TLA:

  • СУХОЙ - не повторяйте себя.

Если вынайдите свой код, выполняя «одни и те же» строки кода, повторенные несколько раз, напишите подпрограмму, чтобы сделать это один раз, и вызовите подпрограмму несколько раз.

Это то, к чему стремится мой переписанный код.

0 голосов
/ 28 ноября 2010

В main() и findWord() вы не должны использовать strlen(sizeLineInputX) сразу после чтения файла с fgets() - может не быть '\0' в sizeLineInput2, и у вас будет strlen() чтение за пределамиУ вас есть 512 байт.

Вместо использования fgets используйте fgetc, чтобы прочитать символ по символу и проверить наличие символа новой строки (и даже EOF).UPD: вы сравниваете каждую строку mike2.txt с каждой строкой mike1.txt - я думаю, это не то, что вы хотите.Откройте оба файла по одной вне цикла while в main(), используйте один цикл для обоих файлов и проверьте наличие новой строки и EOF на обоих из них в этом цикле.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...