Metropoli BBS
VIEWER: numb1.c MODE: TEXT (ASCII)
/* NUMB1.C: Utility to number the lines in a file, using the C
   low-level file functions.
   Copyright (c) 1989 Ziff Communications Co.
   PC Magazine * Ray Duncan
*/

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <io.h>

unsigned ifile;                     /* handle for input file */
unsigned ofile;                     /* handle for output file */

char fbuff[256];                    /* file I/O buffer */
char iname[80];                     /* name of input file */
char oname[80];                     /* name of output file */

char newline[] = "\x0d\x0a";        /* MS-DOS logical new-line */

main(int argc, char *argv[])
{
    char *p, q[10];                 /* scratch pointer, buffer */
    int line = 1, length;           /* line number, length */

    if(argc < 2)                    /* make sure filename present */
    {
        fprintf(stderr,"\nnumb1: missing filename\n");
        exit(1);
    }

    strcpy(iname, argv[1]);         /* get input filename */
    strcpy(oname, argv[1]);         /* build output filename */
    if(! (p = strchr(oname, '.')))  /* point to extension */
        p = strchr(oname, '\0');
    strcpy(p, ".$$$");              /* temp. name for new file */

                                    /* open input file */
    ifile = open(iname, O_RDONLY | O_BINARY);

                                    /* create output file */
    ofile = open(oname, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, S_IWRITE);

    if((ifile == -1) || (ofile == -1))
    {
        fprintf(stderr,"\nnumb1: open or create error\n");
        exit(1);
    }

    while(length = rline())         /* read line from input file */
    {                               /* until end of file reached */
        sprintf(q,"%04d\t",line++); /* format line number */    
        write(ofile,q,strlen(q));   /* write line number */
        write(ofile,fbuff,length);  /* write line text */
    }       

    close(ifile);                   /* close input file */
    close(ofile);                   /* close output file */

    strcpy(p, ".bak");              /* build .BAK filename */
    unlink(oname);                  /* delete previous .BAK file */
    rename(iname, oname);           /* make original file .BAK */
    strcpy(p, ".$$$");              /* give new file same name */
    rename(oname, iname);           /* as original file */
}

/*  Read line from input file and return its length including
    the new-line delimiter character(s), leaving the line's
    text in 'fbuff'.  Returns 0 if end of file or new-line
    delimiter not found.
*/

int rline(void)
{
    char *p;                        /* pointer to delimiter */
    int i, j;                       /* scratch variables */

                                    /* read chunk of input file */
    i = read(ifile, fbuff, sizeof(fbuff)-1);
    if(i == 0) return(0);           /* exit if end of file */
    else fbuff[i] = 0;              /* otherwise store null byte */

    p = strstr(fbuff, newline);     /* search for delimiter */
    if(p == NULL) return(0);        /* none found, indicate EOF */
    j = p-fbuff+strlen(newline);    /* calculate line length */

                                    /* back up file pointer */
    lseek(ifile, (long) (j-i), SEEK_CUR);
    return(j);                      /* return length of line */     
}
[ RETURN TO DIRECTORY ]