версия 1.0.0.0 (4-02-2012) - Comlib (СБС) - самописная библиотека Си

Forums:

В первой версии библиотека выглядит так (не забудь подправить написание инклудов) =

/* это обобщенная самописная библиотека функций языка си - в дальнейшем я буду стараться расширять её))
если кто готов поделиться завершённой самостоятельной функцией - всегда пожалуйста - можете
указать ссылку на свой блок и ваше имя - в комментария к заголовку функции -
но не забывайте о тех ,кто учиться программировать - комментируйте код))*/
#include stdio.h>
#include stdlib.h>

#include "comlib.h"

/*конструкция из трёх строк определит в какой операционной системе мы находимся*/
#if defined(_WIN32) || defined (_WIN64) 
	#define  IN_WINDOWS 1

#endif

/*функция выполняыет Посторчное сравнение двумерных массивов в си (например строк, счиатнных из двух текстовых файлов)
и выведет результат на экран*/
 int tdarrs_cmp(char **arr1,char **arr2, FILE *rfp)/* функция сравнивает два двумерных массива с символами. си выводит результат сравнения в консоль и (дополнительно) в текстовый файл , указателем на который является третий аргумент*/
 {  /* */


	   int k=0; /* число строк - номер строки */
	   int n1=1; /* признак сущетвования для  первого массива элемента с номером строки, меньше либо равным текущем k*/
	   int n2=1; /* признак сущетвования для  второго массива элемента с номером строки, меньше либо равным текущем k*/
	   // putchar(k); ////
	   /*ниже потратим десяток строк на проверку корректности переданных данных*/
	   if (!rfp) 
	   { 
	     printf("[(!)Warning= file pointer for tdarrs_cmp is NULL ]\n");
	     rfp=fopen("compRESULT.txt","w");
	   }
	    if (!arr1) 
	   { 
	     printf("[(!)Warning= first array is NULL ! ]\n");
	   }
	     if (!arr2) 
	   { 
	     printf("[(!)Warning= second array is NULL ! ]\n");
	   }
	   printf("\n\n[%s]\n", "...comparation of two two-demision arrays showing is started...");
	   printf("===========\n");
	    fprintf(rfp,"=============\n");
	   while ((n1)||(n2))
		{ 
		   
		   fprintf(rfp,"(%i)",k); // пишем номер строки в файл
			printf("(%i)",k); // пишем номер строки в консоль
			
		//	putchar('('); putchar(k); printf(")\n");// пишем номер строки в консоль
			//fputc('(',rfp); fputc(k,rfp); fprintf(rfp,")\n"); // пишем номер строки в файл
	
		  if ((n1)&&(*(*(arr1+k)))==EOF) n1=0;/* опускаем флаг присутствия в массиве строк при текущем значении k*/
		  if ((n2)&&(*(*(arr2+k)))==EOF) n2=0; /* опускаем флаг присутствия в массиве строк при текущем значении k*/
		  
		 /* printf("[n1 = %i]", n1); printf("[n1 = %i]", n1); printf("[k = %i]", k); */
		  if ((n1==1)&&(n2==1))
		  {	  
			  if (!(strcmp(*(arr1+k),*(arr2+k)))) printf(" (+)");  else printf(" (-)");
		  }
		   else printf(" (-)");
		   
		  if (n1) 
		  {
			
			printw(*(arr1+k),'\n'," | [","]"); // пишем в консоль
			fprintw(rfp,*(arr1+k),'\n'," | [","]"); // пишем в файл 
		  } else
		   {       	   
			  printf(" | [__________]");
			  fprintf(rfp," | [__________]");		  
		   }
		  if (n2)
		   {
			printw(*(arr2+k),'\n'," | [","]"); // пишем в консоль
			fprintw(rfp,*(arr2+k),'\n'," | [","]"); // пишем в файл
		   } else
		   {       	   
			  printf(" | [__________]\n");
			  fprintf(rfp," | [__________]\n");		  
		   }
		    fprintf(rfp,"\n-------------------------\n");
			printf("\n---------------------\n");
		  k++;
		}
		
		printf("-----------\n");
	    fprintf(rfp,"-----------\n");
		fclose(rfp);
		return 0;
}

 /*  функция выводит двумерный массив в виде последовательности строк в консоль - си функция*//* */
 int tdarr_show(char **arr)
 {/* */
     int n=0; /* число символов в текущей строке */
	 int i=0; /* номер текущего символа в текущей строке*/
	 int k=0; /* число строк - номер строки */
	 putchar('\n');
	 printf(" \n[%s]\n", "...two-demision array showing is started...");
	// *(*(arr+10)+i) = '0';
     while (*(*(arr+k)+i)!=EOF)
	{
	  printf("%s", *(arr+k));
	  k++;
	
	}
	return 0;
 }

/* сохранение текста(строки со всем текстом) из файла в виде двумерного массива символов (массива строк) char**  = язык си функция*/
 char** tfile_to_tdarr(FILE *fp) /*text file to two-dimensional array of char = c*/
 { /* */
     char** arr;
    int n=0; /* число символов */
	int k=0; /* число знаков переноса строк строк */
	int i=0; /* число символов в строке*/
	char *strff; /*переменная в которую мы сохраним все сиволы файла в виде одномерного массива tfile_to_array */
	int n2=0; /*длина текста файла*/
	
	strff = full_file_r(fp, NULL, 5);/* считываем строку из переданного в */
    /* printf("%s\n", strff); */	
	/* сначала посчитаем сколько у нас всего переносов символов в строке*/
	
	printf("[%s]\n", "...text file conversion is started..."); 
	while (*(strff+n)!='\0')
	{
		 if (*(strff+n)=='\n') k++; else if(*(strff+n+1)=='\0') k++; 
		 n++;
	}
	arr = (char**)calloc(k+1,sizeof(char*)); /* выделяем память в массиве для указателней на k+1 строк 
	                                         - в последней мы в конце этой функции разместим единственный символ конца файла EOF*/

	*(arr+k) = (char*)malloc(1); /* выделяем память для символа конца файла в единственной ячейке последней "строки" массива */	
	*(*(arr+k))=EOF;   /*ЗАПИСЫВАЕМ СИМВОЛ КОНЦА ПОТОКА EOF В ПЕРВУЮ И ЕДИНСТВЕННУЮ ячейку последней строки нашего массива*/
	 
	printf("\n[%s = %i ]\n", "...number of lines had been found out", k+1);
	k=0;
	n=0;
	
	/* далее в цикле будем подсчитывать символы в каждой строке и выделять соответствующий объём памяти для строке массива*/
	while (*(strff+n)!='\0')
	{
	  i++;
	  if  (*(strff+n)=='\n') /*если мы встретили сиимвол переноса строки ,то....*/
	  {	  
		  *(arr+k) = (char*)malloc(i+1); /*...выдеоляем память для этой строки , по числу символов + 1 для добавления стандартного '\0' , которые мы в ней встретили (вместе с символом конца строки)*/
		//  printf("[the %i  line  size = %i]\n", k, sizeof(*(arr+k)));
		  i=0; /*...сбрасываем счётчик символов в конкретной строке - так как возможно мы перейдём к новой*/
		  k++; /*...наращиваем счётчик строк*/
	  } else if (*(strff+n+1)!='\0') *(arr+k) = (char*)malloc(i+1);
	  n++;
	  /* printf("[n = %i]", n); printf("[k = %i]", k); printf("[i = %i]", i); */
	}
	if (k==0) *(arr+k) = (char*)malloc(i); /*сработает в случае если переносов строк в файле вообще не было*/
	printf("\n[%s]\n", "...the quantity of symbols in file in each line had been found out...");
	
	i=k=n=0; /* обнуляем все переменнные-счётчики */
	
	/* теперь заполняем размеченный массив данными -третий раз читая всю исходную (переданную в функцию) строку*/
	n2 += strlen(strff)-1;
	//printf("[strlength = %i]\n", n2+1);
	while (*(strff+n)!='\0')
	{  
	 /* printf("[n = %i]", n); printf("[k = %i]", k); printf("[i = %i]", i); */
	   *(*(arr+k)+i)=*(strff+n);/* сохраняем  очередной символ текущей строки k*/
	/*  putchar(*(*(arr+k)+i)); */
	  if  (*(strff+n)=='\n') /* если мы встретили символ переноса строки, то....*/
	  {    
          *(*(arr+k)+i+1)='\0';  /*завершаем нашу строку спец символом*/	  
		  k++; /* увеличиваем счётчик строк*/
		  i=-1; /* сбрасываем счётчик символов в строке аж до -1 , т.к. последняя строка этого цикла как раз вернёт ноль*/
	  } else if (*(strff+n+1)!='\0') /*если последний значащий символ читаемого файла - это не знак переноса строки 
	                                    (мы можем понять , что текущий символ последний в считанном потоке по завершающему его спец
										  символу '\0' добавленному функцией fgets()), то.....*/
	     *(*(arr+k)+i+1)='\0'; /*...то опять же завершаем последнюю строку нашего массива спецсимволом*/
	  n++;
	  i++;
	}
	return arr;
 }

FILE *openfilefor(FILE *fp,char *prompt, char *mode)/*функция открывает файл в си  с выводом уведомлений */
{
   char filename[200];  /*место для указания пути выделяем с запасом*/
   	printf("[%s]\n", "...program waits for file name's specification...");
	 if (prompt)  printf("[%s]\n", prompt);
	 scanf(" %s",filename); /*считываем данные без пробелов (т.к. перед % есть пробел в строке формата)*/
	 inputcl();
	 if (fp=fopen(filename, mode)) 
	    {
		   printf("___%s___\n", "file is open");
            return fp;
		}
	   else 
	    { 
		    printf("%s\n", "(!) Error = File openning was failed. ");
            return NULL;			
		}
		
}
/*функция открывает файл и возвращает ошибку в случае если открыть не удалось (где напишет какой именно файл не удалось открыть)*/
FILE *openfileforme (char *fn , char *mode) 
{
   FILE *fp;
   	printf("\n[%s]\n", "...open file for me now...");

	 if (fp=fopen(fn,mode)) 
	    {
		   printf("[%s]\n", "file is open");
            return fp;
		}
	   else 
	    { 
		    printf("%s = %s\n", "(!) Error = File openning was failed. ", fn);
            return NULL;			
		}

}

/*чтение строки любой длинны в языке си С C - без констант и т.п. - */
 /*reading line of free demension - of free length (arbitrary)
 функция fgets() в качестве последнего считанного символа возвращает '\0' - так что наша строка всего
будет отдеделена от "мусора", который может оказаться в хвосте (размер "хвоста" не привысит размер
единовременно читаемого блока)*/
 char *simple_read_all( char * prompting_message , size_t user_block_size)  /* make sure that the input is clear when you call this function */ 
 {           /**/
    char *result;
	
    /*variables and  initialization*/
	size_t block_size ;
	if (user_block_size)  block_size = user_block_size;  /*если пользователь указал собственный , то выбираем его как рабочий*/
	   else  block_size = 5; /*иначе используем стандартный блок длинной = 5*/

	  char  *block, *temp;
	size_t size = block_size;
	size_t n = 0; /* здесь будет храниться размерность считанной строки*/
	/*printf("\n=[%s]", "[" .prompting_message. " ]" . "\n");*/

	if ( prompting_message)  
	{
	  printf("%s \n", prompting_message); /* show message wich specify the reason of input reading - for examp "input clearing" */
	}
	 /*function itself */
	 
	result = block = (char*)malloc(size); /*выделяем блоку и строке результата память длинной , равной длинне блока разового чтения*/
	 
	if (!result) return NULL; /*если при выделении памяти произошла ошибка - отражаем это в переменной результата*/
	 
	*result = '\0'; /* используем это  присвоивание как признак успешности - см. дальнейшие комментарии после цикла*/
	  /*этот цик*/
	for (;;) /*этот цикл - ключевой в работе данной функции*/
	{
		if (fgets(block, block_size, stdin) == NULL) /*читаем блок данных стандартой длинн и размещаем данные в переменной "блок"*/
		  break; /* если при чтении произошла ошибка   - выходим из цикла */ 
		 
		n += strlen(block);
		 
		if (result[n - 1] == '\n') /* если последний сивол считанной строки - это символ конца строки, то.....*/
		break; /*...выходим из цикла */
		 
		size += block_size; /* наращиваем размерность строки результата на величину, равную длинне стадартного блока чтения*/
		temp = (char*)realloc(result, size); /* переразмещаем данные по адресу возвращаемой строки в новой области большего размера - сохраняем адрес этой области в вспомогаетльную переменную */
		 
		if (temp == NULL)
		break;
		 
		result = temp; /* сохраняем адрес новой области памяти из вспомогательной переменной в оригинальную переменную результата*/
		block = result + n; /* перемещаем указатель записи очередного блока данных на первую свободную ячейку памяти в новой области данных*/
	}
	 
	if (result[0] == '\0') /* если в предыдущем цикле нам не удалось ничего прочитать - освобождаем память,которую "держит" указатель на строку-результат и отражаем неуспешность чтения на возвращаемом значении функции*/
	{
		free(result); /*...освобождаем память,которую "держит" указатель на строку-результат...... */
		result = NULL;/*....и отражаем неуспешность чтения на возвращаемом значении функции*/
	}
	if ( prompting_message)  printf("[%s] \n", "Data was read!");  /* show message wich notify about the end of reading input" */
	return result;
}


/*считывание файла любой длины в строку - сохранение 
считывание всех данных из файла в строковую переменную на языке си;
функция fgets() в качестве последнего считанного символа возвращает '\0' - так что наша строка всего
будет отдеделена от "мусора", который может оказаться в хвосте (размер "хвоста" не привысит размер
единовременно читаемого блока)*/
char *full_file_r(FILE *fp ,char * prompting_message , size_t user_block_size)  /* make sure that the input is clear when you call this function */ 
 {           /**/
    char *result;
	
    /*variables and  initialization*/
	size_t block_size ;
	if (user_block_size)  block_size = user_block_size;  /*если пользователь указал собственный , то выбираем его как рабочий*/
	   else  block_size = 5; /*иначе используем стандартный блок длинной = 5*/
	   
	if (!fp) fp =stdin; /*если поток не указан - будем читать из стандартного*/

	  char  *block, *temp;
	size_t size = block_size;
	size_t n = 0; /* здесь будет храниться размерность считанной строки*/
	/*printf("\n=[%s]", "[" .prompting_message. " ]" . "\n");*/

	if ( prompting_message)  
	{
	  printf("%s \n", prompting_message); /* show message wich specify the reason of input reading - for examp "input clearing" */
	}
	 /*function itself */
	 
	result = block = (char*)malloc(size); /*выделяем блоку и строке результата память длинной , равной длинне блока разового чтения*/
	 
	if (!result) return NULL; /*если при выделении памяти произошла ошибка - отражаем это в переменной результата*/
	 
	*result = '\0'; /* используем это  присвоивание как признак успешности - см. дальнейшие комментарии после цикла*/
	  /*этот цик*/
	for (;;) /*этот цикл - ключевой в работе данной функции*/
	{
		if (fgets(block, block_size, fp) == NULL) /*читаем блок данных стандартой длинны и размещаем данные в переменной "блок"*/
		  break; /* если при чтении произошла ошибка   - выходим из цикла */ 
		 
		n += strlen(block);
		 
		if (result[n - 1] == EOF) /* если последний сивол считанной строки - это СИМВОЛ КОНЦА ФАЙЛА, то.....*/
		break; /*...выходим из цикла */
		 
		size += block_size; /* наращиваем размерность строки результата на величину, равную длинне стадартного блока чтения*/
		temp = (char*)realloc(result, size); /* переразмещаем данные по адресу возвращаемой строки в новой области большего размера - сохраняем адрес этой области в вспомогаетльную переменную */
		 
		if (temp == NULL)
		break;
		 
		result = temp; /* сохраняем адрес новой области памяти из вспомогательной переменной в оригинальную переменную результата*/
		block = result + n; /* перемещаем указатель записи очередного блока данных на первую свободную ячейку памяти в новой области данных*/
	}
	 
	if (result[0] == '\0') /* если в предыдущем цикле нам не удалось ничего прочитать - освобождаем память,которую "держит" указатель на строку-результат и отражаем неуспешность чтения на возвращаемом значении функции*/
	{
		free(result); /*...освобождаем память,которую "держит" указатель на строку-результат...... */
		result = NULL;/*....и отражаем неуспешность чтения на возвращаемом значении функции*/
	}
	if ( prompting_message )  printf("[%s] \n", "File was read");  /* show message wich notify about the end of reading input" */
	if (!result) printf("%s \n", "(!) Error data from wasn't read !");
	
	return result;
}

/* эта функция очистит стандартный поток ввода stdin (обычно - консоль)*/
int inputcl(void)
{
   #if defined IN_WINDOWS 
     fflush(stdin); // если мы в виндоус - просто очищаем поток
   #else // если же нет  -то , так сказать, работаем дальше
   
    printf("\n[%s]\n", "If nothing take place - press enter to continue the program execution.");
    while (getchar() != '\n'); /*remove \n  or other useless data*/
   #endif
   return 0;
}

/*функция printw ("print without") - выведет в консоль строку , игнорируя указанный символ - 
в частности можно игнорировать перенос строки(знак новой строки)*/
int printw(char * str, char outstr , char *stxt , char * etxt )
{ 
  int n=0;
  char* errmes =  " Error(!) = printw() function  does not support such parameter \n " ;
  if (stxt) printf("%s",stxt);
  while (*(str+n)!='\0')
  {
     if (*(str+n)!=outstr) putchar(*(str+n));
	 n++;
  }
  if (etxt) printf("%s",etxt);
  
  return 0;
}
/*функция fprintwf (" filestriam print without ") - аналогична printw() ,
 но дополнительно можно указать  файл, в который следует произвести запись -
если требуется стандартный поток вывода - просто передайте null )*/
int fprintw(FILE *fs , char * str, char outstr , char *stxt , char * etxt )
{ 
  int n=0;
  char* errmes =  " Error(!) = printw() function  does not support such parameter \n " ;
  if (stxt) fprintf(fs,"%s",stxt);
  while (*(str+n)!='\0')
  {
     if (*(str+n)!=outstr) fputc((*(str+n)),fs);
	 n++;
  }
  if (etxt) fprintf(fs,"%s",etxt);
  
  return 0;
}

ну и конечно же заголовочный файл =

#ifndef  MYCOMLIB_H
#define  MYCOMLIB_H



int tdarrs_cmp(char **,char **, FILE *);
FILE *openfileforme (char *, char *);
char** tfile_to_tdarr(FILE *);
int tdarr_show(char **);
char *full_file_r(FILE * ,char *  , size_t );
int inputcl(void);
FILE *openfilefor(FILE *,char *,char *);
char *simple_read_all( char * , size_t);
int printw(char * , char , char *, char *);
int fprintw(FILE * , char * , char  , char * , char *  );

#endif