Чтение строки произвольного размера с выводом сообщения комментария и настройкой размера блока читаемых данных на си (язык си)

Forums:

Итак , читаем строку любой длины (не "длинны")

  
 /*чтение строки любой длины в языке си С C - без констант и т.п. - */
 /*reading line of free demension - of free length (arbitrary)*/
 /* убедитесь, что поток ввода пуст, в момент вызова этой функции */ 
 char *simple_read_all( char * prompting_message , size_t user_block_size)  
 {           /**/
    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;
}

более общий вариант данной функции - случай где реализовано чтение из файла - смотри здесь =http://fkn.ktu10.com/?q=node/179

Не нравится мне, что она аллоцирует память внутри себя. Плохо это.

Если не критичен чистый си, то лучше поюзать вот эту сиплюсплюсную функцию:
http://devtips.livejournal.com/513.html#...

vedro-compota's picture

  • 1)разве выделение памяти - это плохо ?))
  • 2) да, задача рассматривается в рамках чистого си)

_____________
матфак вгу и остальная классика =)