Хрестоматия по программированию на Си в Unix




Текстовая обработка. Хрестоматия по программированию на Си в Unix - стр. 4


npage = 1; /* первая страница имеет номер 1 */ fline = 0; /* текущая строка файла - 0 */

resetsheet(); /* зачистить буфер листа */ while( fgets(inbuf, sizeof inbuf - 1, fpin ) != NULL ){ register l = strlen( inbuf ); if( l && inbuf[l-1] == '\n' ) inbuf[--l] = '\0' ; fline++; untab ( inbuf ); addsheet( inbuf, fpout ); } if( !(Sline == topline && Shalf == 0)) /* если страница не была только что зачищена ... */ flushsheet(fpout); fprintf(stderr, "%d строк, %d листов.\n", fline, npage-1); } /* Вызов: pr < файл > /dev/lp */ void main (){ printcopy(stdin, stdout); }

Файл-принтер имеет в UNIX имя /dev/lp или подобное ему, а в MS DOS - имя prn.

Напишите программу, которая построчно считывает небольшой файл в память и печатает строки в обратном порядке. Указание: используйте динамическую память функции malloc() и strcpy().

Объясним, почему желательно пользоваться динамической памятью. Пусть мы знаем, что строки имеют максимальную длину 80 символов и максимальное количество строк равно 50. Мы могли бы хранить текст в двумерном массиве:

char text[50][80];

занимающем 50*80 = 4000 байт памяти. Пусть теперь оказалось, что строки файла в действительности имеют длину по 10 букв. Мы

используем 50 * (10 + 1) = 550 байт не используем 4000 - 50 * (10 + 1) = 3450 байт

(+1 нужен для символа '\0' на конце строки).

Пусть мы теперь пишем

char *text[50]; int i=0;

и при чтении очередной строки сохраняем ее так:

char buffer[81], *malloc(), *gets(); while( gets(buffer) != NULL ){ text[i] = (char *) malloc(strlen(buffer)+1); /* +1 для хранения \0, который не учтен strlen-ом */ strcpy(text[i++], buffer); }

то есть заказываем ровно столько памяти, сколько надо для хранения строки и ни байтом больше. Здесь мы (если sizeof(char *)==4) используем

50 * 4 + 50 * (10 + 1 + 4) = 950 байт массив указателей + заказанная malloc память

(+4 - служебная информация malloc), но зато у нас не остается неиспользуемой памяти. Преимуществом выделения памяти в виде массива является то, что эта память выделится ГАРАНТИРОВАННО, тогда как malloc()-у может не хватить памяти (если мы ее прежде очень много захватывали и не освобождали free()). Если malloc не может выделить участок памяти требуемого размера, он возвращает значение NULL:

if((text[i] = malloc(....)) == NULL) { fprintf(stderr, "Мало памяти\n"); break; }




Содержание  Назад  Вперед