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




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


Распечатка строк:

for(--i; i >= 0; i-- ){ printf("%s\n", text[i]); free( text[i] ); }

Функция free(ptr) "освобождает" отведенную ранее malloc()ом или calloc()ом область памяти по адресу ptr так, что при новых вызовах malloc() эта область может быть переиспользована. Данные в освобожденной памяти ПОРТЯТСЯ после free(). Ошибочно (и опасно) освобождать память, которая НЕ БЫЛА отведена malloc()-ом!

Организация текста в виде массива ссылок на строки или списка ссылок на строки, а не в виде двумерного текстового поля, выгодна еще тем, что такие строки проще переставлять, сортировать, вставлять строку в текст, удалять строку из текста. При этом переставляются лишь указатели в линейном массиве, а сами строки никуда не копируются. В двумерном же байтовом массиве нам пришлось бы для тех же перестановок копировать целые массивы байт - строки этой текстовой матрицы.

Напишите программу, печатающую строки файла в обратном порядке. Не считывать файл целиком в память! Следует использовать метод "обратного чтения" либо метод "быстрого доступа" к строкам файла, описанный в главе "Работа с файлами".

/* Инвертирование порядка строк в файле. * Используется та идея, что файл-результат имеет тот же * размер, что и исходный */ #include <sys/types.h>

#include <sys/stat.h>

#include <stdio.h>

#define BUFS 4096 /* максимальная длина строки */

void main(int argc, char **argv ) { FILE *fp; struct stat st; long len; char buffer[ BUFS+1 ]; FILE *fpnew; /* инверсный файл */ int lgt;

if( argc != 2 ){ printf("Error: must be filename\n"); exit(1); } if( (fp= fopen( argv[1], "r" )) == NULL ){ printf( "Can not open %s\n", argv[1] ); exit(2); } stat( argv[1], &st ); /* fstat(fileno(fp), &st); */ len = st.st_size; /* длина файла в байтах */

if( (fpnew = fopen( "inv.out", "w" ))== NULL ){ printf("Can not create file\n"); exit(3); }

while( fgets( buffer, sizeof buffer, fp ) != NULL ){ lgt = strlen( buffer ); fseek(fpnew, len - lgt , 0); /* Помните, что смещение у lseek и fseek * это число типа long, а не int. * Поэтому лучше всегда писать * lseek(fd, (long) off, whence); */ len -= lgt; fprintf( fpnew, "%s", buffer ); /* или лучше fputs(buffer, fpnew); */ } fclose( fp ); fclose( fpnew ); }




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