[net.sources] Printing a file backwards

sdawkins@hpda.UUCP (Scott Dawkins) (10/04/85)

This is a (very) short C program that will print out a file
with the lines in the reverse order.  It 'fgetc()'s its way through
the file to count the number of characters, then backs up, spiting
out lines as it goes.  It does an fseek() and two fgets() for each
character in the file, so it does lots of disk accesses, but it
is still O(n), and will work for any size file, at least any file
with fewer characters then the maximum long int on your machine.

scott dawkins
(I wonder if Hewlett-Packard owns this code?)
{hplabs|ucbvax}!hpda!sdawkins

<<<<<<<<<<<<<<<<<<<<<<<cut here>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

/*  backwards - print a file with the lines in the reverse order.
 *  Hewlett-Packard Cupertino  October 3, 1985
 *  Scott Dawkins {ucbvax|hplabs}!hpda!sdawkins
 */
#include <stdio.h>

main(argc, argv)
int argc;
char **argv;
{
	FILE *in_file;    /* input file */
	long int count;   /* number of characters in the file */
	int c;	   	  /* input character */
	char out_line[BUFSIZ], *position; /* building space for lines */

	if ((in_file = fopen(argv[1], "r")) == NULL){
		fprintf(stderr, "backwards:  can't open file %s\n", argv[1]);
		exit(1);
		}

	/* find out how many characters are in the file */
	for (count = 0; (c = fgetc(in_file)) != EOF; ++count)
		;
	--count;

	out_line[BUFSIZ-1] = '\0'; /* be a nice UNIX citizen */
	position = &(out_line[BUFSIZ-2]);

	/* read the characters in the file in backwards order, printing
	 * out lines as they are formed (backwards!).
	 */
	for ( ; count >= 0; --count){
		fseek(in_file, count, 0);
		c = fgetc(in_file);
		if (c == '\n'){
			printf("%s", position);
			position = &(out_line[BUFSIZ-2]);
			*position = c;
			}
		else
			*(--position) = c;
		}
	printf("%s", position);  /* catch the last (first?) line */
	fclose(in_file);
	}

paul@sesame.UUCP (Paul Ruel) (10/08/85)

My feed's been unreliable recently, so I hope I'm not too untimely wih this
followup...In keeping with the UN*X philosophy of using big complicated tools
to solve small, inconsequential problems (:->), I suggest that you do the
following to reverse lines in a file:

	1)  Edit the file using `vi';
	2)  `O'pen a line and type the following:

		:1m'a^[-ma

	    Note that the `^[' means an ESCape;
	3)  Delete this line into macro `a' by typing `"add' when positioned
	    on the just created line (the `' are NOT typed);
	4)  Move your cursor to some line in the file and mark that line
	    as line `a' by typing `ma';
	5)  Type `@a' and *poof* all the lines in the file (above the marked
	    line) will be reversed!

The reversing process is terminated with a message from `vi' which reads:

	Move to a moved line

which, despite its appearance, _means_: `The reversing is done'.

By the way, this works on my 3b2/300 `vi', I hope it works on yours.  `vi'
macro experimentation is a _lot_ safer than playing `hack' on your employer's
dime.  Yes, you _can_ get `vi' stuck in loops, etc.  I've got a number of
visual display time wasters written in `vi' macros.

dave@pyramids.OZ (Dave Horsfall) (10/16/85)

> with the lines in the reverse order.  It 'fgetc()'s its way through
> the file to count the number of characters, then backs up, spiting
> 
> scott dawkins
> {hplabs|ucbvax}!hpda!sdawkins
> 
> 	/* find out how many characters are in the file */
> 	for (count = 0; (c = fgetc(in_file)) != EOF; ++count)
> 		;
> 	--count;
> 
What's wrong with "stat" ?  Or isn't that "portable"?
(Yes - I know, KRE - we don't export net.sources back to the yanks.
This is a sincere request for information no matter who can answer it.)
--
Dave Horsfall VK2KFU	 ISD: +61 2 438-1266   VTL: 248181000
Lionel Singer Group	 STD:  (02) 438-1266
20 Waltham St		ARPA: munnari!pyramids.oz!dave@SEISMO
Artarmon  NSW  2064	UUCP: seismo!munnari!pyramids.oz!dave
AUSTRALIA		 ACS: dave@pyramids, dave@elecvax, dave@runx
	"V7 was the last Unix"

mcewan@uiucdcs.CS.UIUC.EDU (10/24/85)

> My feed's been unreliable recently, so I hope I'm not too untimely wih this
> followup...In keeping with the UN*X philosophy of using big complicated tools
> to solve small, inconsequential problems (:->), I suggest that you do the
> following to reverse lines in a file:
> 
> 	1)  Edit the file using `vi';
> 
> 	(Complicated sequence of instructions)

It's a lot easier to type ":g/^/.m0".


			Scott McEwan
			{ihnp4,pur-ee}!uiucdcs!mcewan

"There are good guys and there are bad guys. The job of the good guys is to
 kill the bad guys."