Can backspace escape cancel a new-line escape? - c

I'm working with ubuntu.
Code:
printf("Hello\n\b world");
I get on terminal:
Hello
world
Why does backspace not cancel the \n?
Is there a hierarchy in chars?
How can I delete special chars?

Your question goes beyond the scope of the C language: printf("Hello\n\b world"); outputs the bytes from the format string, possibly translated according to the text mode handling of newlines:
on unix systems, the bytes are output to the system handle unmodified.
on Microsoft legacy systems, the newline is converted to CR LF and the other bytes transmitted unmodified.
If the standard output is directed to a file, the file will contain the translation of the newline and a backspace (0x08 on most systems).
If the standard output goes to a terminal, the handling of the backspace special character is outside the program's control: the terminal (hardware, virtual, local or remote...) will perform its task as programmed and configured... Most terminals move the cursor left one position on whatever display they control, some erase the character at that position. If the cursor is already at column 1, it is again system dependent whether backspace moves the cursor back to the end of the previous line, whatever that means. Many systems don't do that and keep the cursor at column 1. This seems consistent with the behavior you observe.

This is what the C standard says (in C 2018 5.2.2 2) about the new line character:
Moves the active position to the initial position of the next line.
and backspace:
Moves the active position to the previous position on the current line. If the active position is at the initial position of a line, the behavior of the display device is unspecified.
Note that the backspace character is not specified to erase a previous character. It is specified to cause a certain action on a display device.
Recall that C was developed in an era when teletypes and other physical printing devices were in common use. Many of these devices could only push the paper upward. Once a new line character caused the paper to be pushed upward, there was no way to move it downward again.
Additionally, some early video displays, or the software driving them, emulated physical printing and did not support going back a line, at least in some of their modes of operation.
On displays where one could move the cursor freely, it is not clear what a backspace from the beginning of a line should do. Consider a display which has 80 columns, numbered from 1 to 80, and the last line printed contained 40 characters, followed by a new line. When we backspace, we move the cursor back to that line, but which column do we move it to? Column 80, the last one of the display? Or column 40, the last one where something was printed? Different devices might handle this differently. Note that the latter choice requires the device to remember the length of each line, an added burden on early computing machinery. (My high school’s cheap display terminals did not have enough memory to remember all the text in a 24×80 display. I think it was only 1024 bytes, enough for 12.8 lines of 80 characters. If you wrote complete lines of text, it would scroll earlier lines off the display, keeping only the last 12.)
Because of these variations in behavior, the C standard did not specify the details of backspacing from the start of a line.
You ask about a “backspace escape” canceling a “new-line escape.” However, the escape sequences are irrelevant here; they are in a different layer of representation than the operations of the characters:
Inside a string literal, \b and \n are escape sequences. As the compiler translates the program, it replaces these with a backspace character and a new line character. Then they are no longer escape sequences; they are simply characters in a string.
When you write the characters with printf, they are transmitted as characters in a stream.
When the characters are sent to a display device (because that is what the stream is connected to), they produce the actions in the 5.2.2 2 text cited above.

Those escape sequences \b and \n represent control characters. A control character is a special character that, well, controls the behavior of the output device in some special way. When you say
printf("A");
it prints the (ordinary) character A to the screen. But when you say
printf("\n");
it doesn't print anything, instead it moves the cursor down to the beginning of the next line.
Now, the meaning of \b is not "cancel the character to the left". The control character \b does not "cancel" anything. What it does is just move the cursor one character to the left, if it can. But if the cursor is already at the left edge, it probably can't.
Once upon a time, and especially when the output was going to a printer that actually printed on paper, it was common to do things like
printf("this is u\b_n\b_d\b_e\b_r\b_l\b_i\b_n\b_e\b_d\b_\n");
or
printf("this is b\bbo\bol\bld\bd\n");
to print underlined or bold words by overprinting. These examples obviously rely on the move-one-to-the-left behavior of \b. These examples prove that the behavior of \b is not anything like "canceling"!
It sounds like you think \b might somehow affect the string it's part of.
It sounds like you think \b might somehow be processed by your C compiler, or by the C library.
It sounds like you think that the string "abc\bdef" might get converted to "abdef".
But none of these things is true. The backspace character \b is interpreted by your screen or your printer, or whatever output device your program is "printing" to. The interpretation of control characters like \b is mostly up to your output device. It is mostly not a property of the C programming language.

Related

Why can't we print ASCII values from 0 to 31?

#include<stdio.h>
int main()
{
for(int i=0;i<=31;i++)
printf("%c",i);
}
when we try to run this code then nothing prints
what is the reason for it ?
C is printing them, but perhaps your terminal is not displaying them. This distinction is important because the terminal is responsible for interpreting the output of your program, printing letters, moving the cursor around, changing colors and such.
By historical convention the first 32 characters of the ASCII table are considered "control characters", some of which are printable, some like backspace which move the cursor, others like BEL which can make your terminal beep.
Different terminals may display these differently, or not at all.
It's worth noting that ASCII pre-dates modern "glass" terminals and that these codes were used to move the print-head around on the page. Early machines used teletypes to communicate with them and a line-feed would crank down the paper one line, a carriage return move the cursor back to the start of the line, much like the physical carriage return on a typewriter which would move the "carriage" back to the first column.
These were pretty elaborate elecromechanical contraptions that didn't have any modern circuitry in them, yet they could still process ASCII data, at least for those using ASCII, as there are other character sets like EBCDIC that co-existed with ASCII.
As these characters were never intended to be printed, so they don't have a standard visual representation in ASCII.
With "extended ASCII", as used in DOS, there are symbols defined for them because it seemed like a waste otherwise. These don't have control-code meanings, typically you write them directly to the console character buffer in order to see them.
You can, it's just that most of them are non-printable control characters that most shells ignore. If you pipe stdout to a file, the file will contain those characters, it's just the shell that doesn't know what to do with them. Some of them are handled by shells (e.g. the line feed and backspace characters) but others are just nonsensical (e.g. end of transmission, data link escape) and get ignored, or replaced with a different character for display (often a space or a question mark or the like).

BBC Basic: Inserting a control character without occupying space in Mode 7

I'm using mode 7 ("Teletext mode") on my Beeb. I'd like to print a string of unbroken characters with an coloured text control character in the middle, as-per this mock-up:
However, I can't work how this can be done. The control character needs to occupy space in the output:
PRINT CHR$129;"STACK"CHR$132;"OVERFLOW"
I read up on held graphics mode, but this only seems to allow me to repeat the last used graphics symbol, instead of inserting a space when I print a control character. When I do try this with text I just get an additional space for the held graphics character:
PRINT CHR$129;"STACK"CHR$158;CHR$132;"OVERFLOW"
Is this possible? Can I print a control character without getting a visible space?
Or perhaps there is a way to insert a control character followed by a backspace, to claim back the occupied space but retain the control code effect?
It is not possible to treat the text characters as graphics characters when using the 'held graphics' character. A good example of using 'held graphics' can be found here: http://www.riscos.com/support/developers/bbcbasic/part2/teletext.html
You also cannot use the backspace character to go back one space as each control code takes up one space on the screen.
OK so this is a bit of a fudge; but it was an answer to my problem so I will share it here for all those BBC Micro / Teletext developers struggling with the same problem...
My challenge was to avoid a noticeable space between the two coloured words. Control characters must exist in the text and occupy a character (either as a space or a copy of the last used block graphic).
Therefore, by inserting a space between every character I was able to make the text appear as one word (albeit with slightly excessive letter spacing):
PRINT CHR$129;"S T A C K"CHR$132;"O V E R F L O W"
This had the desired effect for me - it may not for some others. The only other route I could see available was to render the whole text in block graphics, which would occupy significantly more screen space than the approach I settled for.
This is from memory, I recall that CHR$(8) moves the cursor one place to the left.
Put that just before the "O":
PRINT CHR$(129);"STACK";CHR$(132);CHR$(8);"OVERFLOW"
Sadly my BBC Model B is, I believe, in my parents' attic, so I can't test this.

Newline character in C other than \n? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 years ago.
Improve this question
Is there a replacement of \n in C? Can I jump to next line without using \n? I came across this question and I cannot seem to figure out a way..
#include < stdio.h>
void main()
{
printf("A");
printf("B");
}
I want it to print
A
B
And not
AB
But I cannot use \n.
You can use puts("A"); puts("B");.
To output \n without writing \n you could simply printf("%c",10);, or char c=10;write(1,&c,1);, or 100 other ways to output ascii 10.
But if you would like to avoid the newline character completely, the answer varies. It's not C or your code that actually decides to go to a new line, but whatever the device is that displays your output.
E.g. a terminal, or a line printer, or a web browser showing html.
Suppose you are outputting to a browser, the answer would be <br>
If you are outputting to an xterm terminal, \033[1B moves the cursor one line down. The output a carriage return \r to move to the beginning of the line.
So for example:
printf("test\033[1B\r123");
will output (in an xterm)
test
123
As an alternative to puts(), you can use the octal equivalent of \n: \012.
E.g.
#include <stdio.h>
int main()
{
printf("A\012");
printf("B\012");
return 0;
}
\n means "new line". \rmeans "carriage return". These characters have their origin from old form-feed printers, which needed both, one to advance the paper to a new line, one to return the carriage with the print head to the start of the line.
Different OS-es have uses different combinations of the two to indicate a new line in text:
Unix (and Linux, Mac OSX, etc) uses only \n
Windows uses \r\n
Mac OS up to version 9 uses only \r
There is no canonical platform-independent way in the C standard libraries to represent the "System"'s newline/carriage return character. However, many other languages and/or libraries have implemented this, e.g:
Java: System.getProperty("line.separator")
.NET: System.Environment.NewLine
However, if you have an output stream open on a text file, the standard C libraries should translate \n to whatever is necessary to indicate a new line on the current system.
I'd simply use:
printf("A%cB",10);
In C the escape sequence \n represents a character that belongs to the basic execution character set.
In particular, one can be sure that a new-line character exists when our C programs are running.
More important: \n is mapped to 1 and only 1 character, whose code is a positive integer number in the range of the type char.
However, the behaviour of the display devices can produce other results.
For example, when we send a character \n to a text file under Windows, this is replaced by the sequence of two characters \x0D\x0A (LF+CR, that is: Line Feed + Carriage Return).
The standard C99 or C11 says:
(5.2.2) \n (new line) Moves the active position to the initial position of the next line.
The meaning of that (in every system that prints several lines in its standard display device), the "effect" of sending a character \n is "advance to the next line" and "go to the beginning of that line". It is the sum of "line feed" and "carriage return" operations.
In DOS/Windows this is equivalent to send the sequence of these two characters: '\xD', '\xA'.
In Linux/Unix this is equivalent to send the only character '\xD'.
More details here: http://en.wikipedia.org/wiki/Newline
Summarizing, we have to distinguish betwenn the character \n by itself, and the semantic related to \n when is considered as a control character in C.
You can "produce" a new line just by sending the character '\n' with putc() or printf().
By using \n is the better way to do that.
Another very good alternative is that pointed out by #1'': to use the function puts(str).
This function appends a new-line at the end of the string str.
I think is not at all a good idea to try this other alternatives:
printf("%c", 10); // 10 == 0x0A
printf("%c", 13); // 10 == 0x0D
printf("\x0A"); // CR
printf("\x0D"); // LF
You are not solving the problem properly, because your program becomes system dependent.
Valid for Windows, Linux or what?
Worst: in theory, the standard C does not ensures that you even have correspondence between the ASCII/Unicode code numbers for the characters and the characters used in the system your program will run. This issue involves to the control characters, too.
So, you cannot be sure that 0x10 means "carriage return" and 0x13 means "line feed".
To be sure of that, it is necessary to check the existence of the following macro:
__STDC_ISO_10646__
(That macro, if exists, is a long int number containing information about the version of Unicode supported by your compiler.)
The important thing is: if the macro __STDC_ISO_10646__ is not defined, you cannot have certainty about the codes assigned to the characters in your system.
Thus, it cannot be used the "magic numbers" 10 and 13.

How to replace already-printed text in the command prompt?

A lot of times I've seen text-based programs which replace text which has already been printed. For instance, imagine a program where the progress is printed as
Loading: 5%
and then it says
Loading: 10%
and so on, without printing new text which is appended?
How is this done? I haven't seen any such functions available in the library (in this case C). I have an idea, though: There is a character you can write which returns the prompt to the beginning of current line (\r I believe). Could this be used to "overwrite" what you've already printed to the command prompt?
In most consoles, writing a bare carriage return \r without a newline after it will return the cursor to the beginning of the current line, allowing you to overwrite the existing text. Writing the backspace character \b also moves the cursor back one character.
For simple behavior, such as a progress indicator, this is all you need. For more complex behavior, you need to control the terminal through non-standard means. On Unix-based systems, the ncurses library can be used—it gives you full control over the cursor location, text color, keyboard echoing, more fine-grained keyboard input, and more.
On Windows, there's a suite of functions for manipulating consoles, and they can do mostly the same things as Unix consoles.
One way that I have seen is to just print the backspace character a number of times and then replace whatever you erased with the new text.
The backspace character is an ASCII control character represented by \b.

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