What's the Use of '\r' escape sequence? - c++

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.

Related

How do I rewrite a line of text in a console project? c++

I'm working on a c++ console project and i would like to show a percentage without making a new line each time (so that the window doesn't get clogged with thousands of lines).
Is there a way of removing the last line that was printed or something to say that the next time that i output a line it should replace the current line?
You can use a \r (carriage return) to return the cursor to the beginning of the line:
This works on windows and Linux.
From: Erase the current printed console line
You could alternatively use a series of backspaces.
string str="Hello!";
cout << str;
cout << string(str.length(),'\b');
cout << "Hello again!";
From: http://www.cplusplus.com/forum/unices/25744/
Maybe mark as duplicate? I am really not sure how.
A simple example that I tested on Linux would be:
std::cout << "Some text to display..." << "\t\r" << std::flush;
Here the \t adds a tabulation to handle slightly varying string lengths and \r sends the cursor back at the start of the line (as mentioned in other answers).
std::flush is required to guarantee that the line is displayed without jumping to the next line.
This is very platform-dependent and terminal-dependent. But, you may want to look at ncurses for a start: http://linux.die.net/man/3/ncurses
For Windows: How can I overwrite the same portion of the console in a Windows native C++ console app, without using a 3rd Party library?
For Linux: https://unix.stackexchange.com/questions/43075/how-to-change-the-contents-of-a-line-on-the-terminal-as-opposed-to-writing-a-new

If printf("%c%c",'A',8); deletes A, why can't printf("%c%c",'\n',8); delete new line? How can I do it?

How can I delete a new line character once printed in a C code? I want to write a bunch of lines and delete them and after a pause print some other lines then delete them...in a loop. Like a real time update without scrolling. I can print characters and delete them by printing backspace character but once I print new line, I can't delete the line created. Is there any way to achieve this?
The backspace character '\b' (ASCII 8) moves to the previous position within the line.
If you are under xterm or vt100 compatible you can make use of console codes:
#include <stdio.h>
#include <unistd.h> /* for sleep() */
int main(void)
{
printf("Line\n");
sleep(2);
printf("\033[A"); /* move cursor one line up */
printf("\033[K"); /* delete line */
return 0;
}
As an alternative you can take a look to ncurses (Unix) or conio2 (Windows / MINGW)
The backspace character does not "remove" anything. It's just a character like anything else, in terms of the bytestream/file contents. However, when printed to a terminal, backspace moves the cursor position one unit to the left, allowing the next printed character to replace it on the screen. On most terminals, it does nothing if you're already at the left-most position, but even if it did work there, it would not know where to move to on the previous line.
0x08, or \b in ASCII, is just a (special)character that is sent to the stdout. How stdout handles it is up to implementation.
Reference: Usage of \b and \r in C

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.

strange cout behaviour

I compiled on Ubuntu a program that was developed for (and works on) Windows. On Ubuntu, I see this code:
string s = values_[9];
cout << s << endl;
cout << s << "x\n";
producing this output:
high
xigh
The expected output for the second line is "highx". I know that the value of values_[9] is originally read from a file (written on Windows). Printing other strings seems to work normally.
What's going on here?
Run the command with its output piped through cat -A. Probably either the value of s, or the output produced by endl is giving you a '\r' character, which typically sends the cursor back to the beginning of the line.
EDIT: On further thought, the stray '\r' is almost certainly in s, not in the output produced by endl. I had thought there might be some funny locale stuff going on, but having s equal to "high\r" explains the symptoms.
EDIT2: If your system doesn't have cat -A (it's a GNU extension), try cat -v or, if you're desperate, od -c.
The string you're printing has a carriage return '\r' in it. What's happening is that you're printing high, then the carriage return, which puts the cursor back on the start of the line. Then, when you print the x, it overwrites the first letter on the line.
You should either remove the carriage return from the source file (e.g. with dos2unix(1) or many other options), or change your code to strip the carriage return after reading the file in.
What is probably happening, is that there is a \r in values_[9].

Undo a newline (\n) printed to command line

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!