[comp.lang.c] How do I get printf to move to a tab position?

jwf0978@tahoma.UUCP (John W. Fawcett) (05/18/88)

I have what may actually be a simple question, but I could not find an
answer in my K & R.  I would like to be able to tab over to a certain
position on a line and place some text there without overwriting text that
was already on the line, similar to the "X" format descriptor in FORTRAN.
The closest I can come so far is to use a "%20s", but this overwrites
whatever was there.  Any help out there?  

			    Thanks,

			    John


John W. Fawcett		      Voice: (206) 237-2564
Boeing Commercial Airplanes   UUCP: ..!uw-beaver!ssc-vax!shuksan!tahoma!jwf0978
P.O. Box 3707, M/S 66-04
Seattle, WA  98124-2207

chris@mimsy.UUCP (Chris Torek) (05/19/88)

In article <242@tahoma.UUCP> jwf0978@tahoma.UUCP (John W. Fawcett) writes:
>... I would like to be able to tab over to a certain position on a
>line and place some text there without overwriting text that was
>already on the line, similar to the "X" format descriptor in FORTRAN.
>The closest I can come so far is to use a "%20s", but this overwrites
>whatever was there.

Do what FORTRAN does: print on a card punch or line printer.  Then
those pesky spaces will not overwrite the non-spaces. :-)

Seriously, most FORTRAN implementations have no idea how to back up;
they simply keep track of the current column, and when asked to get
to column 30 (via T, not X: X means blanks), print 30-current_column
blanks.  This approach works fine in C as well, but you have to count
the columns yourself.

Your operating system (which is not part of the C language) most
likely provides a higher-level screen management library, if you have
more ambition.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

jep@oink.UUCP (James E. Prior) (05/25/88)

In article <242@tahoma.UUCP> jwf0978@tahoma.UUCP (John W. Fawcett) writes:
>I have what may actually be a simple question, but I could not find an
>answer in my K & R.  I would like to be able to tab over to a certain
>position on a line and place some text there without overwriting text that
>was already on the line, similar to the "X" format descriptor in FORTRAN.
>The closest I can come so far is to use a "%20s", but this overwrites
>whatever was there.  Any help out there?  
>
>			    Thanks,
>			    John
>
>John W. Fawcett		      Voice: (206) 237-2564
>Boeing Commercial Airplanes   UUCP: ..!uw-beaver!ssc-vax!shuksan!tahoma!jwf0978

printf() is pretty simple.  It is so simple that it doesn't know or care 
what column you're at on a line.

The following trick, albeit ugly, might work:

   printf("...\r%*s...",...,width,"",...);

I admit to not having tried it.  If it works, but it still too ugly,
or unsuitable due to the overprinting, you'll probably have to resort
to something else than printf().

Good luck,
-- 
Jim Prior    {ihnp4|osu-cis}!n8emr!oink!jep    jep@oink.UUCP

Pointers are my friend.

cpp90221@dcscg1.UUCP (Duane L. Rezac) (05/26/88)

In article <242@tahoma.UUCP>, jwf0978@tahoma.UUCP (John W. Fawcett) writes:
> ....  I would like to be able to tab over to a certain
> position on a line and place some text there without overwriting text that
> was already on the line.....

 
NOTE: our posting program indicated that my original attempt at posting
      this may not have made it out, so I am posting it with a diffrent
      program. If this is a duplicate posting, my appologies.


I am a newcomer to C, just finishing my first class in C, but this may help.


If you are using an ansi terminal, this code may help.  I wrote this printl
function in order to let me print to a specific screen position. If you are
trying to print to a printer, you could replace the ansi cursor movement 
statement with the appropriate command sequence for your printer.
(If someone knows a better way to do this, Please post it. As I said, I am 
 a novice at C and there may be better ways to do this.)

/* printl - print at location x,y  x,y = screen position,
            control=printf template,
             args=data to be printed

            This is used just like printf except that an x,y screen position
            is passsed. (i.e. printl(10,10,"%s",name) prints the string name
            at column 10, row 10)*/
printl(x,y,control,args)
unsigned char *control;
unsigned args;
int x,y;
{
  printf("\33[%d;%dH",x,y); /* prints ansi cursor movement command to stdout*/
  printf(control,args);     /* print data */
}

I hope this helps.

shankar@hpclscu.HP.COM (Shankar Unni) (05/27/88)

Or even uglier and simpler, try programming direct escape sequences if it is
a terminal application:

   printf ("\033&a%dC%s", column, text);   /* HP escape sequences here.. */

Drawbacks:

  1. Non-portable.
  2. Ugly.

If you *really* want to do a portable terminal-based application, use "curses"
or any of its equivalents.

If you want to do this rigmarole with disc files, try some dorktran-like
carriage-control mechanism:

   printf ("%cRESTofFORMAT", CCTL, ...);
	/*
	 * where CCTL ==
	 *	' ' for normal pre-spacing (i.e. start next line)
	 *	'0' for normal double-spacing
	 *	'+' for overstrike (write over current line with
	 *	    NON-DESTRUCTIVE spacing..
	 *	'1' for page eject
	 *	any other char implies a ' ' (may or may not be eaten up).
	 *	or anything else that strikes your fancy
	 */

Then, write a post-processor to translate all this to simple text files
(should be pretty simple). Can even be built in to your application...

Shankar Unni.

chris@mimsy.UUCP (Chris Torek) (05/29/88)

In article <284@dcscg1.UUCP> cpp90221@dcscg1.UUCP (Duane L. Rezac) writes:
>(If someone knows a better way to do this, Please post it. ...

Okay:

>printl(x,y,control,args)
>unsigned char *control;
>unsigned args;
>int x,y;
>{
>  printf("\33[%d;%dH",x,y); /* prints ansi cursor movement command to stdout*/
>  printf(control,args);     /* print data */
>}

x and y are actually used as row and column respectively; so this
should be `y, x' or `row, col'.  In addition, you should use `vprintf'
if you have it, so as to have the correct types and number of arguments
at all times.  Also, the control (format) argument should be `char *'.

#include <stdio.h>
#include <varargs.h>

int
#ifdef __STDC__
rcprint(int row, int col, char *fmt, ...)	/* dpANS */
#else
rcprint(va_alist)				/* K&R &/
	va_dcl
#endif
{
	int nchars;
	va_list ap;
#ifndef __STDC__
	int row, col;				/* K&R */
	char *fmt;

	va_start(ap);
	row = va_arg(ap, int);
	col = va_arg(ap, int);
	fmt = va_arg(ap, char *);
#else
	va_start(ap, fmt);			/* dpANS */
#endif
	nchars = vprintf(fmt, ap);		/* both */
	va_end(ap);
	return (ferror(stdout) ? EOF : nchars);
}
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris