Пример 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 www.abyss-group.narod.ru
Си в UNIX

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

Hosted by uCoz