Пример 9

/* Вставка/удаление строк в файл */
#include <stdio.h>

#define INSERT_BEFORE 1		/* Вставить строку перед указанной */
#define INSERT_AFTER  2		/* Вставить строку после указанной */
#define DELETE        3		/* Удалить строку  */
#define REPLACE       4		/* Заменить строку */

/* К каждой строке linenum должно относиться не более 1 операции !!! */
struct lineop {
    char    op;			/* Операция                     */
    long    linenum;		/* Номер строки в файле (с 0)   */
    char   *str;		/* Строка (или NULL для DELETE) */
};

long lineno;                          /* номер текущей строки */
int fileChange (char *name,           /* имя файла */
		struct lineop ops[],  /* задание   */
		int nops              /* число элементов в массиве ops[] */
){
    FILE     *fin, *fout;
    static   char   TMPNAME[] = "  ?  ";
    char     buffer[BUFSIZ];
    register i;
    struct   lineop tmpop;

    if ((fin = fopen (name, "r")) == NULL)
	 return (-1);
    if ((fout = fopen (TMPNAME, "w")) == NULL) {
	 fclose (fin); return (-1);
    }
    lineno = 0L;
    while (fgets (buffer, BUFSIZ, fin) != NULL) {
	if( nops ) for (i = 0; i < nops; i++)
	    if (lineno == ops[i].linenum) {
		switch (ops[i].op) {
		    case DELETE: /* удалить */
			break;
		    case INSERT_BEFORE: /* вставить перед */
			fprintf (fout, "%s\n", ops[i].str);
			fputs (buffer, fout);
			break;
		    case INSERT_AFTER: /* вставить после */
			fputs (buffer, fout);
			fprintf (fout, "%s\n", ops[i].str);
			break;
		    case REPLACE: /* заменить */
			fprintf (fout, "%s\n", ops[i].str);
			break;
		}
	   /* переставить выполненную операцию в конец массива и забыть */
		tmpop = ops[nops-1]; ops[nops-1] = ops[i]; ops[i] = tmpop;
		nops--; goto next;
	    }
    /* иначе строка не числится в массиве ops[] : скопировать */
	fputs (buffer, fout);
next:
	lineno++;
    }
    fclose (fin); fclose (fout); rename (TMPNAME, name);
    return nops;  /* число несделанных операций (0 - все сделано) */
}

struct lineop myops[] = {
	{ DELETE,         2L,     NULL                 },
	{ INSERT_BEFORE,  0L,     "inserted before 0"  },
	{ INSERT_BEFORE,  10L,    "inserted before 10" },
	{ INSERT_AFTER,   5L,     "inserted after 5"   },
	{ DELETE,         6L,     NULL                 },
	{ INSERT_AFTER,   8L,     "inserted after 8"   },
	{ INSERT_AFTER,   12L,    "inserted after 12"  },
	{ REPLACE,        3L,     "3 replaced"         }
};

void main( void ){
  int n;
  n = fileChange( "aFile", myops, sizeof(myops)/sizeof(struct lineop));
  printf( "Строк в файле: %ld; осталось операций: %d\n", lineno, n);
}
/*
исходный файл            получившийся файл
line 0                   inserted before 0
line 1                   line 0
line 2                   line 1
line 3                   3 replaced
line 4                   line 4
line 5                   line 5
line 6                   inserted after 5
line 7                   line 7
line 8                   line 8
line 9                   inserted after 8
line 10                  line 9
			 inserted before 10
			 line 10
		Строк в файле: 11; осталось операций: 1
*/

© Copyright А. Богатырев, 1992-95
Си в UNIX

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