Найти и заменить в файле C - PullRequest
0 голосов
/ 09 августа 2010

Проблема была в найти и заменить строку в файле C .

Я новичок в C Files. Я пробовал следующий код, но я не получил никакого вывода:

    #include<stdio.h>
    #include<string.h>
    int main()
    {
        FILE *f1,*f2;
        char *src,*dest,*s1,ch,ch1,ch2,ch3;
        int i;
        f1=fopen("input.txt","rw");
        f2=fopen("dummy.txt","rw");
        src="mor";
        dest="even";
        while(ch!=EOF)
        {
         ch=fgetc(f1);
         if(ch==src[0])                      //Finding 1st char of src
         {
         fgets(s1,strlen(src),f1);
         if(strcmp(src+1,s1)==0)         //Finding occurance of "src" in file
         {
          fseek(f1,strlen(src)-1,SEEK_CUR);
          while(ch1!=EOF)             //Copying remaining data into another file
          {
          ch1=fgetc(f1);
          fputc(ch1,f2);
          }
      fseek(f1,-strlen(src),SEEK_CUR);
      for(i=0;i<strlen(dest);i++)  //replacing "src" with "dest"
      {
          ch2=dest[i];
          fputc(ch2,f1);
      }
      fclose(f1);
      f1=fopen("input.txt","a");
      while(ch3!=EOF)      //Appending previosly copied data into 1st file
      {
          ch3=fgetc(f2);
          fputc(ch3,f1);
      }
     }
   }
 }
     fclose(f1);
     fclose(f2);
}

Содержимое файла input.txt - это "утро".

Просьба указать ОШИБКУ в логике , а также дать эффективный код для того же.

Заранее спасибо.

Ответы [ 5 ]

3 голосов
/ 09 августа 2010

Чтение файлов на С обычно немного грязно. Первая проблема, которую я вижу, это способ использования ch в основном цикле. Первый раз

while (ch != EOF)

выполняется, ch неинициализирован, и если он удерживает EOF, основной цикл не будет выполняться вообще. Я обычно использую следующую структуру для чтения из файлов:

FILE *fInput = fopen("input.txt", "r");
int ch; /* need an int to hold EOF */

for (;;)
{
    ch = fgetc(fInput);
    if (ch == EOF) break;

    ...
}

Кроме того, вам может понадобиться прочитать концепцию указателя файла. Например, после прочтения оставшейся части src вы fseek() вперед и пропускаете еще несколько символов, прежде чем копировать данные в f2. По сути, вы читаете m, читаете orfgets() - и в нераспределенный буфер s1, который в ближайшем будущем приведет вас к ка-буму), пропустите еще 2 символа (теперь ваш указатель) это, наконец, n из «morning»), скопируйте «ng» в f2, попробуйте записать EOF в f2 в этом цикле (отсюда и вышеупомянутый шаблон для чтения до EOF), отыщите два символа назад (которые могут один раз завершиться Вы достигаете EOF, мои функции файла C в наши дни немного устарели), пишите "even" в f1 (что должно, если я ошибаюсь из-за поиска после EOF, установить входной файл в "mornieven", и не изменяться это если я прав). Таким образом, я не думаю, что код делает то, что вы намереваетесь делать.

Я бы порекомендовал создать вашу функцию. Каждое из следующего может быть написано как программа, которую вы должны проверить и закончить, прежде чем перейти к следующему шагу:

  1. безопасно прочитайте файл и распечатайте его
  2. обнаружить содержимое src и распечатать остальную часть ввода
  3. сохранить оставшуюся часть ввода во второй файл вместо печати
  4. замените src на dest в первом файле и проигнорируйте остальные (поскольку вы открываете входной файл с помощью 'rw', это урезает остальную часть ввода). Возможно, вам потребуется выполнить функцию fseek (), чтобы очистить состояние EOF. Также посмотрите на ftell(), чтобы записать позицию, к которой вы можете вернуться, используя fseek()
  5. наконец, скопируйте все, что вы сохранили, во второй файл после замены src на dest (здесь не нужно закрывать f1. Но лучше открыть f2 как запись, закрыть после копирования из первого файла и открыть заново как читать, чтобы выполнить копирование обратно в f1).

Кроме того, когда вам нужен буфер (например, s1), просто используйте пока достаточно большой массив, но посмотрите на функции malloc() и free() для динамического распределения памяти в подобных ситуациях.

2 голосов
/ 09 августа 2010

Один простой способ сделать замену - сначала прочитать весь файл в буфер

, например

FILE* fpIn = fopen("file.txt","rb");
fseek(fpIn, 0L, SEEK_END);
size_t s = ftell(fpIn);
fseek(fpIn, 0L, SEEK_SET);
void* buf = malloc(s);
fread(buf,s,1,fpIn);

теперь во время записи файла проверьте строку

char src[] = "mor";
char dest[] = "even";
int lenSrc = strlen(src);
int lenDest = strlen(dest);
for (char* ch = buf; ch < buf + s; ++ch)
{
   if ( !memcmp( ch, src, lenSrc ) )
   {
     fwrite( dest, 1,lenDest, fpOut );
     ch += lenSrc;
   }
   else 
   {
     fputc( *ch, fp );
   }
}

отказ от ответственности: не скомпилировал

1 голос
/ 10 августа 2010

Другая проблема заключается в том, что вы объявляете ch как char.fgetc() возвращает int, и на то есть веская причина.Хорошо иметь возможность вернуть любой возможный символ или EOF, поэтому EOF не должен быть символом, поэтому в идеале fgetc() возвращает больший тип, чем char.

Результатчто цикл вполне может никогда не закончиться, поскольку ch не может содержать EOF в некоторой стандартной реализации.Объявите это (и ch1 и ch3) как int.

1 голос
/ 09 августа 2010

На первый взгляд, я вижу, что ваш код для вызова fgets неверен.Вы не распределили память и читаете строку в неинициализированный указатель.Чтение в массив или динамически выделенную память.

1 голос
/ 09 августа 2010

Вы печатаете не то, что в выводе.Выведите «ch», а не указатель файла.

 while(ch!=EOF) 
 { 
     ch=getc(f1); 
     printf("%c",ch); 
 } 
 while(ch!=EOF) 
 { 
     ch=getc(f2); 
     printf("%c",ch); 
 }

Кроме того, f2 закрывается в конце во время вывода.Вам придется открыть его снова (так же, как вы делаете с f1.)

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