Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > Сравнение текстовых файлов


Автор: koyot 6.4.2008, 19:27
Помогите, пожалуйста с решением задачи:
Есть 2 текстовых файла. Нужно сравнить их содержание без учета лишних пробелов, непечатных символов и регистра букв. Результат – файлы равны или не равны.
Помогите с общим алгоритмом решения, если можно, также подскажите функции, осуществляющие сравнение.

Автор: archimed7592 6.4.2008, 20:22
Цитата(koyot @  6.4.2008,  19:27 Найти цитируемый пост)
Помогите с общим алгоритмом решения

1. Считываешь оба файла в отдельные буфера.
2. Фильтруешь буфера на предмет ненужных символов(которые не учитываются при сравнении).
3. В итоге у тебя осталось два буфера, которые нужно сравнить побайтово. strcmp тебе в помощь.

1 и 2 можно совместить, т.е. считывать посимвольно и сразу решать, добавлять в буфер символ или нет. Если использовать буфферизованный поток(stdin и ф-ция getc), то разницы в производительности не будет(может быть даже лучше будет).

Автор: koyot 13.4.2008, 15:25
Цитата

2. Фильтруешь буфера на предмет ненужных символов(которые не учитываются при сравнении).


т.е., если я правильно понял, нужно указать символы, которые при сравнении не нужно учитывать?
или наоборот - указать только те, которые нужно учитывать

Добавлено через 8 минут и 3 секунды
А можно ли только нужные символы 1 файла занести в 1 массив, символы другого файла - в др. массив, а затем сравнить массивы?

Автор: archimed7592 13.4.2008, 16:42
Цитата(koyot @  13.4.2008,  15:25 Найти цитируемый пост)
т.е., если я правильно понял, нужно указать символы, которые при сравнении не нужно учитывать?
или наоборот - указать только те, которые нужно учитывать

Лучше сверять символ с набор не нужных т.к. их по идее многим меньше, чем нужных, т.е. более рационально.


Цитата(koyot @  13.4.2008,  15:25 Найти цитируемый пост)
А можно ли только нужные символы 1 файла занести в 1 массив, символы другого файла - в др. массив, а затем сравнить массивы? 

Да, об этом я и говорю:
Цитата(archimed7592 @  6.4.2008,  20:22 Найти цитируемый пост)
1 и 2 можно совместить, т.е. считывать посимвольно и сразу решать, добавлять в буфер символ или нет. Если использовать буфферизованный поток(stdin и ф-ция getc), то разницы в производительности не будет(может быть даже лучше будет). 


Автор: jonie 14.4.2008, 00:23
1: тупо читаешь посимвольно с первого файла, пропуская ненужное. Нашли нужный символ.
начинаем читать также второй файл. Нашли символ2
если символ2!=символ1 тогда return false
если конец обоих файлов одновременно (в смысле значимых символов) return true;
если конец одного из файлов, но не конец второго (в смысле значимых символов) return false;
иначе goto1

если вернется true, то файлы одинаковые

Автор: koyot 20.4.2008, 17:06
Благодарю за помощь

Автор: koyot 20.4.2008, 21:28
2jonie:
Цитата

тупо читаешь посимвольно с первого файла, пропуская ненужное.


Не подскажешь функцию, которая исключает те или иные символы либо разрешает осуществить поиск только указанных символов(диапозона символов)?

Автор: jonie 21.4.2008, 00:38
а ты if попробуй )

Автор: darkart 26.4.2008, 01:00
Цитата

без учета лишних пробелов

Считаю, что 1 пробел - норма. И лучше все-таки потестить.
Код

#include<stdio.h>
#include<ctype.h>

const unsigned short MAX_FILE_NAME_LENGTH=256;//максимальная длина имени файла

bool flcmp(const char* szFileNameFirst,const char* szFileNameSecond)
/*функция сравнения 2 файлов с именами szFileNameFirst и szFileNameSecond*/
{
  FILE* fFirst=fopen(szFileNameFirst,"r");//открытие первого файла для чтения
  if(!fFirst)//если открытие завершилось неудачей считаем, что  не равны
    return false;
  FILE* fSecond=fopen(szFileNameSecond,"r");//открытие второго файла для чтения
  if(!fSecond)//если открытие завершилось неудачей считаем, что  не равны
    return false;
  char cLastFirst,cFirst,cLastSecond,cSecond;//вспомогательные переменные
  cFirst=cSecond='\0';//инициализация переменных
  while(!feof(fFirst)&&!feof(fSecond))
  {
    if(!feof(fFirst))//если еще не конец файла
    {
      cLastFirst=cFirst;//запоминаем предыдущий "правильный символ"
      cFirst=fgetc(fFirst);//читаем текущий символ
      while(!feof(fFirst)&&((cFirst==' '&&cLastFirst==' ')||(cFirst<32)))//пока не конец файла пробрасываем пробелы>1 и символы до 32
        cFirst=fgetc(fFirst);//читаем очередной символ
    }
    if(!feof(fSecond))//если еще не конец файла
    {
      cLastSecond=cSecond;//запоминаем предыдущий "правильный символ"
      cSecond=fgetc(fSecond);//читаем текущий символ
      while(!feof(fSecond)&&((cSecond==' '&&cLastSecond==' ')||(cSecond<32)))//пока не конец файла пробрасываем пробелы>1 и символы до 32
        cSecond=fgetc(fSecond);
    }
    if(tolower(cFirst)-tolower(cSecond)||((feof(fFirst)||feof(fSecond))&&(!(feof(fFirst)&&feof(fSecond)))))//если переведенные в нижний регистр  символы не совпадают или не было изменений в каком-то из файлов
    {
      fclose(fFirst);//закрываем за собой файл
      fclose(fSecond);//закрываем за собой файл
      return false;//не сравнилось:)
    }
  }
  fclose(fFirst);//закрываем за собой файл
  fclose(fSecond);//закрываем за собой файл
  return true;
}

int main(int argc,char* argv[])
{
  char szFileNameFirst[MAX_FILE_NAME_LENGTH];//строка для хранения имени первого файла
  char szFileNameSecond[MAX_FILE_NAME_LENGTH];//строка для хранени имени второго файла
  printf("Please enter first file name:\n");
  gets(szFileNameFirst);//читаем имя первого файла
  printf("Please enter second file name:\n");
  gets(szFileNameSecond);//читаем имя второго файла
  /*печать результата*/
  printf("Result:\n");
  flcmp(szFileNameFirst,szFileNameSecond)?printf("YES\n"):printf("NO\n");
  return 0;
}

Автор: koyot 8.5.2008, 20:33
darkart, спасибо огромное! Я бы таким методом никогда не додумался бы написать программу. Обязательно протестирую и напишу о результатах

Автор: ASMatic 9.11.2009, 20:16
koyot, 

видимо код рабочий....иначе ты бы не забыл написать что он не работает smile 

Автор: koyot 11.11.2009, 14:34
Тема закрыта, благодарю всех за помощь))

Автор: W4FhLF 11.11.2009, 15:34
А мы так переживали всё это время. Ну... хорошо то, что хорошо кончается, расходимся. 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)