/**В этой программе демонстрируется работа со следующими функциями:
Функция -qsort (библиотечная функция быстрой сортировки)
Функция -bsearch (библиотечная функция двоичного поиска)
Функции -fgets, fopen, fprintf, malloc, sscanf и strcmp.
Программа считывает записи двух файлов ввода в виде строк и выводит на принтер или экран:
-записи из файла2, отсутствующие в файле1
-записи из файла1, отсутствующие в файле2
Программа считывает записи обоих файлов и размещает их в двух массивах, которые сортируются в одинаковом порядке с помощью функции qsort. После этого с помощью функции bsearch ищется вхождение очередного элемента одного из массивов в другом массиве. Если элемент не будет найден, отправляется сообщение о том, что запись не найдена. Такая процедура выполняется и для элементов другого массива. В результате создается второй список исключений.
**/
#include <stdio.h> /*библиотечный файл, содержащий /*стандартные функции ввода-вывода*/
#include <search.h> /*библиотечный файл, содержащий qsort*/ #include <sys/errno.h> /*библиотечный файл для обработки
/*стандартных ошибок*/
#define MAXRECS 10000 /*ограничение на размер массива*/
#define MAXSTR 256 /*максимальная длина строки ввода*/ #define input1 "file1" /*первый файл ввода*/ #define input2 "file2" /*второй файл ввода*/ #define out1 "o_file1" /*первый файл вывода*/ #define out2 "o_file2" /*второй файл вывода*/
main() {
char *arr1[MAXRECS] , *arr2[MAXRECS] ;/* массивы для хранения
записей ввода*/
unsigned int num1 , num2; /*счетчики записей
/*ввода. Тип unsigned int
/*гарантирует /*совместимость
/*с библиотечной процедурой qsort.*/
int i ; int compar(); /* функция, которая используется qsort и
/* bsearch*/
extern int errno ; /*переменная для хранения информации об ошибках*/ FILE *ifp1 , *ifp2, *ofp1, *ofp2; /*указатели на файлы
ввода и вывода */
void *bsearch() ; /*библиотечная функция двоичного поиска*/ void qsort(); /*библиотечная процедура быстрой сортировки*/ char*malloc() ; /*функция для выделения памяти*/ void exit() ;
num1 = num2 = 0;
/**Открытие файлов ввода и вывода для чтения и записи **/
if ( (ifp1 = fopen( input1 , "r" ) ) == NULL ) {
(void) fprintf(stderr,"Невозможно открыть %s\n",input1); exit(-1);
}
if (( ifp2 = fopen( input2 , "r" )) == NULL ) {
(void) fprintf(stderr,"Невозможно открыть %s\n",input2); exit(-1);
}
if (( ofp1 = fopen(out1,"w" )) == NULL ) {
(void) fprintf(stderr,"Невозможно открыть %s\n",out1); exit(-1);
}
if (( ofp2 = fopen(out2,"w")) == NULL ) {
(void) fprintf(stderr,"Невозможно открыть %s\n",out2); exit(-1);
}
/**Заполнение массивов данными из файлов ввода. Readline возвращает число записей ввода.**/
if ( (i = readline( arr1 , ifp1 )) < 0 ) {
(void) fprintf(stderr,"В %s нет данных. Выход\n",input1); exit(-1);
} num1 = (unsigned) i; if ( (i = readline ( arr2 , ifp2)) < 0 ) {
(void) fprintf(stderr,"В %s нет данных. Выход\n",input2); exit(-1);
} num2 = (unsigned) i;
/** Теперь массивы можно отсортировать с помощью функции qsort **/
qsort( (char *)arr1 , num1 , sizeof (char *) , compar); qsort( (char *)arr2 , num2 , sizeof (char *) , compar);
/** После сортировки массивов в одинаковом порядке программа создает список элементов, содержащихся только в одном из массивов, с помощью bsearch.
Проверяет все элементы array1 на вхождение в array2 **/
for ( i= 0 ; i < num1 ; i++ ) {
if ( bsearch((void *)&arr1[i] , (char *)arr2,num2,
sizeof(char *) , compar) == NULL )
{ (void) fprintf(ofp1,"%s",arr1[i]);
}
} /**Один список исключений создан **/
/** Проверяет все элементы array2 на вхождение в array1**/
for ( i = 0 ; i < num2 ; i++ ) { if ( bsearch((void *)&arr2[i], (char *)arr1, num1
, sizeof(char *) , compar) == NULL )
{ (void) fprintf(ofp2,"%s",arr2[i]);
}
}
/**Задача выполнена, выход из функции**/
return(0);
}
/**Функция считывает записи из файла ввода и записывает их в два массива.**/
readline ( char **aptr, FILE *fp )
{
char str[MAXSTR] , *p ; int i=0 ;
/**Построчное чтение файла ввода.**/
while ( fgets(str , sizeof(str) , fp )) {
/**Выделение памяти. Если память не будет выделена - выход.**/
if ( (p = (char *)malloc ( sizeof(str))) == NULL ) {
(void) fprintf(stderr,"Недостаточно памяти\n"); return(-1);
} else
{ if ( 0 > strcpy(p, str))
{ (void) fprintf(stderr,"Strcpy не выполнена\n"); return(-1); } i++ ; /*увеличение счетчика записей*/
}
} /**Достигнут конец файла ввода**/ return(i);/*возвращает число прочитанных записей*/
}
/**Нужно отсортировать массивы по значению первого поля записей. Первое поле выделяется с помощью SSCANF**/
compar( char **s1 , char **s2 ) {
char st1[100] , st2[100] ; (void) sscanf(*s1,"%s" , st1) ; (void) sscanf(*s2,"%s" , st2) ;
/**Возвращает результат сравнения строк во внешнюю процедуру**/
return(strcmp(st1 , st2));
}