Clearing output of a terminal program Linux C/C++ - c

I'm interested in clearing the output of a C program produced with printf statements, multiple lines long.
My initial guess was to use
printf("output1\n");
printf("output2\n");
rewind(stdout);
printf("output3\n");
printf("output4\n");
but this produces
output1
output2
output3
output4
I was hoping it would produce
output3
output4
Does anyone know how to get the latter result?

You can have the desired result both for terminal and pipes if you remember to remove the control characters as well. This is hardcoded for two lines.
#include <stdio.h>
int
main ()
{
fputs("output1\n",stdout);
fputs("output2\n",stdout);
fputs("\033[A\033[2K\033[A\033[2K",stdout);
rewind(stdout);
ftruncate(1,0); /* you probably want this as well */
fputs("output3\n",stdout);
fputs("output4\n",stdout);
return 0;
}

Most terminals support ANSI escape codes. You can use a J (with parameter 2) to clear the screen and an H (with parameters 1,1) to reset the cursor to the top-left:
printf("\033[2J\033[1;1H");
Alternatively, a more portable solution would be to use a library such as ncurses, which abstracts away the terminal-specific details.

Once you print something to the terminal you can't easily remove it. You can clear the screen but exactly how to do that depends on the terminal type, and clearing the screen will remove all of the text on the screen not just what you printed.
If you really want fine control over the screen output use a library like ncurses.

You can also try something like this, which clears the entire screen:
printf("\033[2J\033[1;1H");
You can include \033[1;1H to make sure if \033[2J does not move the cursor in the upper left corner.
More specifically:
033 is the octal of ESC
2J is for clearing the entire console/terminal screen (and moves cursor to upper left on DOS ANSI.SYS)
1;1H moves the cursor to row 1 and column 1

As far as C is concerned, stdout is nothing more than a byte stream. That stream could be attached to a CRT (or flat screen), or it could be attached to a hardcopy device like a teletype or even a sheet-fed printer. Calling rewind on the stream won't necessarily be reflected on the output device, because it may not make any sense in context of that device; think about what rewinding would mean on a hardcopy terminal or a sheet-fed printer.
C does not offer any built-in support for display management, so you'll have to use a third-party library like ncurses.

One way, is to do a exec('clear').

In fact, when you capture/redirect your stdout (./program > output.file), there is no way how to remove contents of that file, even printf("\033[2J\033[1;1H"); just adds this sequence of characters into it.

Related

How can I specify the color of particular characters in a String in c?

I am experimenting with colorized text output to the console in c. I know that you are able to change the color of entire printf statements, but I was wondering if I am able to change the text color of individual characters within a printf statement.
In summary, I would like to be able to print out "asdf" with the a being red, the s being green, the d being blue, and the f being orange.
Thank you in advance.
First of all, in C, characters has no color. They are just numbers. So your question is not at all related to C, which doesn't care at all about how your print things.
What you are referring to, is the fact that some terminals accept some control characters to specific how they should render what is sent to them.
Those are just special characters, that are not meant to be printed, but to modify the terminal behavior. There is no guarantee that your terminal understand those control characters. Nor is there any guarantee that they are the same control characters as other terminals.
Some library (such as ncurses) exist that have knowledge on the terminal you are using, and provide helper functions that make this transparent.
All that being said, the way to print in red (well, the most common one, at least) is
printf("\033[31m");
That switch the terminal to red
and
printf("\033[m");
That switches is back to normal.
Those are control characters. So, from C point of view, just characters like any other, to be printed, that is sent to the terminal. It is then up to the terminal to do whatever it sees fit with it.
Being just characters like other, nothing prevent you to mix them with any normal characters,
So your example
printf("\033[31ma\033[32ms\033[34md\033[33mf\033[m\n");
But there is no guarantee it works. You can't really count on it. There is even no guarantee that it won't print some unwanted chars.
I have found a temporary workaround: using multiple printf statements since they do not go to the next line, I do not like this solution very much.

how print in c without jumping to end of text?

I'm very new to coding in general so please excuse any stupid things I say.
I am trying to print (in c) a rather long text using printf() but since it can't all fit on the screen it jumps to the end of the text and the beginning is not visible unless you scroll up. Is there an easy way to have it print the long text but stay at the beginning and allow the user to scroll down as they read before they put in the next command?
On Unix (including Linux and Mac), there are command line programs built in called more and less that does exactly what you describe. more is a program that simply waits for the user to press enter or space before showing the next page of output. less is slightly improved in that it allows vi editor keystrokes (such as j and k) to scroll up and down in the output.
more is also available on the Windows command line as well. You might even be able to find a version of less for Windows as well.
c:\users\selbie> your_program.exe | more
$> ./your_program | less
As to how to do this programmatically, that's a bit more difficult as it would involve measuring the console width and implementing your own scroll buffers. There might be open-source libraries that provide this functionality, but the console environment already has a solution for apps that produce long output.
Not really, though you may find a reasonable and simple solution is to print only a certain number of lines (say 30), then prompt the user to press Enter before display more lines.
You can even find out the current size of the terminal. That's platform specific; for Linux it's explained here: How to get terminal window width?
Not in a standard way, no.
Your output stream in C is just a stream of characters -- scrolling is handled by your terminal.
Depending on your terminal, it may be possible to control scrolling by outputting special characters, like ANSI escape codes. The ncurses library provides a portable way to manipulate terminals.
However, if you just want a more convenient way to look through your output (or really any command output), #selbie's answer is the best: use more or less. This will avoid any extra complexity in your program.

Using C I would like to format my output such that the output in the terminal stops once it hits the edge of the window

If you type ps aux into your terminal and make the window really small, the output of the command will not wrap and the format is still very clear.
When I use printf and output my 5 or 6 strings, sometimes the length of my output exceeds that of the terminal window and the strings wrap to the next line which totally screws up the format. How can I write my program such that the output continues to the edge of the window but no further?
I've tried searching for an answer to this question but I'm having trouble narrowing it down and thus my search results never have anything to do with it so it seems.
Thanks!
There are functions that can let you know information about the terminal window, and some others that will allow you to manipulate it. Look up the "ncurses" or the "termcap" library.
A simple approach for solving your problem will be to get the terminal window size (specially the width), and then format your output accordingly.
There are two possible answers to fix your problem.
Turn off line wrapping in your terminal emulator(if it supports it).
Look into the Curses library. Applications like top or vim use the Curses library for screen formatting.
You can find, or at least guess, the width of the terminal using methods that other answers describe. That's only part of the problem however -- the tricky bit is formatting the output to fit the console. I don't believe there's any alternative to reading the text word by word, and moving the output to the next line when a word would overflow the width. You'll need to implement a method to detect where the white-space is, allowing for the fact that there could be multiple white spaces in a row. You'll need to decide how to handle line-breaking white-space, like CR/LF, if you have any. You'll need to decide whether you can break a word on punctuation (e.g, a hyphen). My approach is to use a simple finite-state machine, where the states are "At start of line", "in a word", "in whitespace", etc., and the characters (or, rather character classes) encountered are the events that change the state.
A particular complication when working in C is that there is little-to-no built-in support for multi-byte characters. That's fine for text which you are certain will only ever be in English, and use only the ASCII punctuation symbols, but with any kind of internationalization you need to be more careful. I've found that it's easiest to convert the text into some wide format, perhaps UTF-32, and then work with arrays of 32-bit integers to represent the characters. If your text is UTF-8, there are various tricks you can use to avoid having to do this conversion, but they are a bit ugly.
I have some code I could share, but I don't claim it is production quality, or even comprehensible. This simple-seeming problem is actually far more complicated than first impressions suggest. It's easy to do badly, but difficult to do well.

Backspace character does not move the cursor back to the previous line in terminal

I am using Ubuntu 12.10, while making a program i observed that the backspace character ('\b') can move the cursor one position back on the same line inside the terminal, but didn't worked when i wanted it to move back to the previous line?
How can i achieve this using C language?
This is really a question about the behavior of your terminal, not C. I don't know any easy way to "backspace to the previous line" aside from "move up one line" followed by "move to end of line" or similar. On Linux, man console_codes will give you good documentation of standard terminal escapes. All relevant terminals are sufficiently similar that, if you just want to do cursor positioning and not fancy color stuff, you should just be able to hard-code the codes.
As Peter said, you could also use a higher-level library like ncurses if you prefer. Whether this makes sense depends a lot on the scope of what you're doing.
the normal terminal is line-orientated, so you have to take a more complex path, like using the curses-library and do the semantics yourself

Isolating stdin and stdout within a terminal

I'm developing a CLI program, in C, for my systems class project, and it needs to display incoming text while maintaining a command prompt. Left alone, the incoming text will saw through whatever one tries to type. In other applications I've seen the incoming text print above(or below) the prompt itself. Is there any way to implement this in ANSI escapes? ncurses seems like overkill.
You can print \r to erase the prompt: It will return the cursor to the beginning of the current line. You can then print your output followed by some spaces to clear out any remaining input characters, newline, and reprint the prompt.
With ANSI sequences or terminal-specific libraries you can do even more, but this I think is all you can do reliably using only ASCII. Apart from printing 242 blank lines to redraw the whole screen, of course.
Edit: Sorry, I didn't answer the ANSI part properly. With cursor movement control codes and printing space over existing characters, you can pretty much do anything, and there are some convenience actions to help you, such as "delete line". But keep in mind that Windows doesn't play nice w/ ANSI post XP, and neither are other systems guaranteed to.
For one thing, if you want to maintain a prompt, while printing, you can not use things like scanf. You have to intercept keyboard events or use a non waiting method to get input. Then you can get the terminal number of lines (n) and print the last n-1 lines of your output, and then a prompt.
my2c

Resources