Undo a newline (\n) printed to command line - c++

printf("Error %d\n", 1);
printf("\nStatus: %d%%", 50);
prints
Error 1
Status: 50%
In this set up, is there any chance to insert Error 2\n between Error 1\n and \nStatus: 50%. I understand that \r and \b can be used to change printed text in the same line (e.g., if there is a single \n between Error 1 and Status: 50%), but can I change text in a previous line?
Thanks!

What #Ryan said.
Explanation why: stdout is some abstract stream that doesn't have to be the terminal. It may be a file, a pipe, a socket, a printer, a text to speech device or whatever. In many cases there is no sense to what you asked to do. Hence you need some library that works with the terminal specifically.

Sorry, you cannot.
But you may issue system calls to clear the whole screen instead, like system("clear") (OS-dependent).
Or use ncurses just as Kos mentioned in the comment.

You could use ANSI Escapesequences to move your "cursor" one line up:
void cursorOnLineUp(void) { printf("\033[1A"); }
Or set it to a specific position:
void setCursor(int column, int row) { printf("\033[%d;%dH", row, column) }
Haven't tried it for C++, but succesfully used it for a simple game in ANSI-C!

Related

Programmatically expand terminal to a specific size

In my output there are certain lines that are refreshed every few seconds. If I resize the terminal by clicking F11, then output is just as I wanted. If terminal isn't big enough some long lines that are refreshed are splitted in two, and because of that, only one part of line is refreshed, and every time line is refreshed I also get new line.
This could be easily avoided if I could specify default size of terminal (resize terminal from my program). Also it would be great if I could forbid user to change terminal size while program is running.
while(1)
{
cout<<"Long line that is refreshed every 5s... \r";
//if line is splited in two lines, \r will return to beginning of that new line
//and the first part of original line would stay as it is(won't be rewrited)
sleep(5);
}
How do I specify a terminal size or stop terminal resizing?
Some terminal emulators (including the default macOS Terminal.app) support being resized/moved/etc in response to printed control sequences. The sequences are fairly standard but not all terminal emulators implement all of them.
For example:
# set terminal width to 50, height to 100
cout << "\e[8;50;100t";
This answer includes an overview of some other available control sequences.
I don't think you can forbid the user to change the terminal size. A better way would be to catch the SIGWINCH signal that is sent to the process everytime the window size is changed, and use the TIOCGWINSZ / TIOCGSIZE ioctl() to get the dimensions.

How do I set cursor position to beginning of line in C++?

So I'm trying to make part of a code where it writes something, then overwrites it. Like this:
10 seconds have passed
11 seconds have passed
12 seconds have passed
without using a new line to print it. So I don't want to use something like this:
std::cout<<"10 seconds have passed\n"
std::cout<<"11 seconds have passed\n"
How do I do this? I'm running Kubuntu Linux
That's what the carriage return character is for: \r. It is named after the mechanism of typewriters that returns the paper carriage to the right so that the typist can continue typing from the beginning of a line. Try this:
std::cout << "10 seconds have passed";
std::cout << "\r11";
Of course, with no delay between the two (except perhaps waiting on I/O), you're unlikely to see the change, but you will at least see the output as 11 seconds have passed with 10 nowhere to be seen.
How to display the carriage return is entirely up to whatever you're outputting to, but this is its intention. For more complex cross-platform terminal output, take a look at ncurses.
#include <conio.h>
#include <consoleapi.h>
void gotoxy(short x, short y)
{
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
COORD position = { x, y };
SetConsoleCursorPosition(hStdout, position);
}
If you need better moving in console.
(i dont know why it not showing corectly #include conio.h
Besides \r (that takes you back to the beginning of the line), you can also use the \b character to get back of one character. If you have to do more complicated stuff, you'll have to use the VT100 escape codes or some library (like ncurses).
Try
cout<<"\roverride"
With no linebreak at the end. The \r means carage return which means to jump to the beginning of a line.
The carriage return '\r' is responsible for moving back to beginning of line.
Not that you have to override all characters that have been written because they are not deleted automatically on display.
And don't forget to call the flush of std::cout because otherwise on unix machines you may not see any results until its flushed.

cursor blinking removal in terminal, how to?

I use the following lines to output my simulation's progress info in my c++ program,
double N=0;
double percent=0;
double total = 1000000;
for (int i; i<total; ++i)
{
percent = 100*i/total;
printf("\r[%6.4f%%]",percent);
}
It works fine!
But the problem is I see the terminal cursor keeps blinking cyclically through the numbers, this is very annoying, anyone knows how to get rid of this?
I've seen some programs like wget or ubuntu apt, they use progress bar or percentages too, but they seems no blinking cursor issue, I am wondering how did they do that?
Thanks!
You can hide and show the cursor using the DECTCEM (DEC text cursor enable mode) mode in DECSM and DECRM:
fputs("\e[?25l", stdout); /* hide the cursor */
fputs("\e[?25h", stdout); /* show the cursor */
Just a guess: try to use a proper number of '\b' (backspace) characters instead of '\r'.
== EDIT ==
I'm not a Linux shell wizard, but this may work:
system("setterm -cursor off");
// ...display percentages...
system("setterm -cursor on");
Don't forget to #include <cstdlib> or <iostream>.
One way to avoid a blinking cursor is (as suggested) to hide the cursor temporarily.
However, that is only part of the solution. Your program should also take this into account:
after hiding the cursor and modifying the screen, before showing the cursor again move it back to the original location.
hiding/showing the cursor only keeps the cursor from noticeably blinking when your updates take only a small amount of time. If you happened to mix this with some time-consuming process, your cursor will blink.
The suggested solution using setterm is not portable; it is specific to the Linux console. And running an executable using system is not really necessary. But even running
system("tput civis");
...
system("tput cnorm");
is an improvement over using setterm.
Checking the source-code for wget doesn't find any cursor-hiding escape sequences. What you're seeing with its progress bar is that it leaves the cursor in roughly the same place whenever it does something time-consuming. The output to the terminal takes so little time that you do not notice the momentary rewrite of the line (by printing a carriage return, then writing most of the line over again). If it were slower, then hiding the cursor would help — up to a point.
By the way — this cursor-hiding technique is used in the terminal drivers for some editors (vim and vile).
Those apps are probably using ncurses. See mvaddstr
The reason the cursor jumps around is because stdout is buffered, so you don't know actually how many characters are being printed at some point in time. The reason wget does not have a jumping cursor is that they are actually printing to stderr instead, which is unbuffered. Try the following:
fprintf(stderr, "\r[%6.4f%%]", percent);
This also has the advantage of not cluttering the file if you are saving the rest of the output somewhere using a pipe like:
$ ./executable > log.data
Press insert key...if that doesn't work then press the fn key in your keyboard.
This will definitely work
Hope this helps

Is there a way to set the console height(in lines)?

Is it possible to set how many lines the console will print before it starts to erase the top ones? For example, is it possible to set it to 3 and only make the last 3 lines be visible? So:
std::cout<<"line 1!"<<std::endl;
std::cout<<"line 2!"<<std::endl;
std::cout<<"line 3!"<<std::endl;
std::cout<<"line 4!"<<std::endl;
system("pause");
Would output:
line 3!
line 4!
Press any key to continue...
^without creating a scroll bar on the side.
I've been trying to use Console::BufferHeight but I can't seem to get it to work. This is the only thing I've been able to find that seems to be close to what I want to do: http://msdn.microsoft.com/en-us/library/system.console.bufferheight.aspx But It just shows how to read it, not how to set the size. And for some reason typing just std::cout<<System::Console::BufferHeight; gives me scope errors. Any help would be greatly appreciated. Thanks!
I think you want this:
SetConsoleWindowInfo
Example,
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
SMALL_RECT rect = {0,0, 100, 100};
SetConsoleWindowInfo(hConsole, TRUE, &rect)
Have a look at these as well (experiment with them):
SetConsoleScreenBufferSize()
SetConsoleScreenBufferInfoEx
There is an example on MSDN here.
Im new to programming also, but I tried:
while(!cin.get())
{
}
and it worked,try to place it in the bottom of the code. It will work wonders on your console!
Try changing its position (put it in the middle of the code)
I'd suggest keeping the lines yourself, in a quick class, say that cycles where to put the next line by using an iterator that is always set to point at the next line to be input into.
Next, use FillConsoleOutputCharacter() to print blanks over the lines you previously had printed there.
Then, use SetConsoleCursorPosition() to four(or however many lines you wanted) lines above where you want your input to start, and output each line in you cycle, starting at the one after your iterator. This prints all the lines in order from eldest to youngest.It's been a while, so my knowledge of C++ is kinda hazy, but this should be pretty simple with the standard library and win32 library.

What's the Use of '\r' escape sequence?

I have C code like this:
#include<stdio.h>
int main()
{
printf("Hey this is my first hello world \r");
return 0;
}
I have used the \r escape sequence as an experiment. When I run the code I get the output as:
o world
Why is that, and what is the use of \r exactly?
If I run the same code in an online compiler I get the output as:
Hey this is my first hello world
Why did the online compiler produce different output, ignoring the \r?
\r is a carriage return character; it tells your terminal emulator to move the cursor at the start of the line.
The cursor is the position where the next characters will be rendered.
So, printing a \r allows to override the current line of the terminal emulator.
Tom Zych figured why the output of your program is o world while the \r is at the end of the line and you don't print anything after that:
When your program exits, the shell prints the command prompt. The terminal renders it where you left the cursor. Your program leaves the cursor at the start of the line, so the command prompt partly overrides the line you printed. This explains why you seen your command prompt followed by o world.
The online compiler you mention just prints the raw output to the browser. The browser ignores control characters, so the \r has no effect.
See https://en.wikipedia.org/wiki/Carriage_return
Here is a usage example of \r:
#include <stdio.h>
#include <unistd.h>
int main()
{
char chars[] = {'-', '\\', '|', '/'};
unsigned int i;
for (i = 0; ; ++i) {
printf("%c\r", chars[i % sizeof(chars)]);
fflush(stdout);
usleep(200000);
}
return 0;
}
It repeatedly prints the characters - \ | / at the same position to give the illusion of a rotating | in the terminal.
The program is printing "Hey this is my first hello world ", then it is moving the cursor back to the beginning of the line. How this will look on the screen depends on your environment. It appears the beginning of the string is being overwritten by something, perhaps your command line prompt.
The '\r' stands for "Carriage Return" - it's a holdover from the days of typewriters and really old printers. The best example is in Windows and other DOSsy OSes, where a newline is given as "\r\n". These are the instructions sent to an old printer to start a new line: first move the print head back to the beginning, then go down one.
Different OSes will use other newline sequences. Linux and OSX just use '\n'. Older Mac OSes just use '\r'. Wikipedia has a more complete list, but those are the important ones.
Hope this helps!
PS: As for why you get that weird output... Perhaps the console is moving the "cursor" back to the beginning of the line, and then overwriting the first bit with spaces or summat.
\r move the cursor to the begin of the line.
Line breaks are managed differently on different systems. Some only use \n (line feed, e.g. Unix), some use (\r e.g. MacOS before OS X afaik) and some use \r\n (e.g. Windows afaik).
As amaud576875 said, the \r escape sequence signifies a carriage-return, similar to pressing the Enter key. However, I'm not sure how you get "o world"; you should (and I do) get "my first hello world" and then a new line. Depending on what operating system you're using (I'm using Mac) you might want to use a \n instead of a \r.
This is from antiquated technology: The old fashion typewriter style of printer. There was a roller (platen) that advanced the paper and a print head that hammered a metal key against an ink fabric.
\r Return the print head to the left side.
\n Advance the platen one line.
If the \n was not issued, you would type over what was on a line (used mostly for underlining text).
To answer the part of your question,
what is the use of \r?
Many Internet protocols, such as FTP, HTTP and SMTP, are specified in terms of lines delimited by carriage return and newline. So, for example, when sending an email, you might have code such as:
fprintf(socket, "RCPT TO: %s\r\n", recipients);
Or, when a FTP server replies with a permission-denied error:
fprintf(client, "550 Permission denied\r\n");
It is quite useful, when you are running on the unix platform, and need to create a text file
which will be opened on the dos platform.
Unix uses '\n' as its line terminator, and dos uses '\r\n' as its line terminator, so you can use it to create a dos text file.