about escape character "\b"

1
2
3
4
5
for(....)
{
  fprintf(fp,"%d ",..);
}
fprintf(fp,"\b\n");


as the codes above show, I want to cancel the last blank using \b and then line feed
but in the printed file, there is adisorder corresponding to '\b', which is a strange square
what is wrong?
my OS is linux
ubutun
It is because '\b' is a terminal escape code... (sans the 'escape' of course ;-)

so it only modifies what you see on the terminal. That is, the terminal adjusts its display to respond to the backspace code, even though it received everything prior to it. A file also receives everything, including the backspace code, but it is not a tty device so the file's content is not modified; it keeps everything you send to it.

If printing an extra blank is a problem, then you should code some extra logic to print the trailing blank on every output except the last.

Hope this helps.
if '\b' doesn't function in canceling the blank before it, what is the purpose of it?
Like Duoas said, '\b' works on the console because it's possible to make the cursor go back. A file is more like a bit bucket, and once you've sent something to it, there's nothing you can do.
The same would happen if you sent the '\b' to the printer.
Yes, exactly.

The '\b' doesn't cancel the character before it -- what it does is instruct the terminal/console device to move the cursor backwards and place a space character at the new cursor position.

The '\b' escape is so called because in C (and C++) it is written using the 'backslash escape sequence'. The '\b' really translates to the ASCII BS code -- or the value 8 -- also writeable as '\010' or '\x08' (...unless you are using an EBCDIC system or some other ancient piece of cruft, in which case it translates to the appropriate code for that system, and is not writeable using the direct character code).

Such values are often called "control codes" because they are special characters designed to control I/O devices, such as your terminal/emulator. This particular control code is also representable as ^H, because to get it you can press the Ctrl+H key combination (instead of the Backspace key directly -- presuming your tty is properly configured -- especially for you folks on *nix systems).

The reason is that terminal card manufactures added-in special abilities to control the device by sending the proper sequence of control codes to it. Most modern systems derive from the venerable VT100 series of terminal devices, which accepted a comprehensive variety of input codes to manipulate the device. DOS/Windows users are familiar with it through the ANSI.SYS driver which hooked into the terminal I/O to provide much of the same capabilities. For you *nixers, the xterm X11 terminal emulator provides this very same interface by default.

The wide variety of terminal devices, however, made simply assuming VT100 compatability a nuisance, particularly as the VT220 was much more powerful and other manufacturers implemented new powers in their own, incompatible way. (That, or their terminals were too dumb to do even VT100 stuff.)

Hence, the termcap library was created to provide a database where user programs could query the terminal capabilities and do cool stuff like positioning the cursor, colors, insert/delete lines, etc, as well as special keyboard input powers, without having to write a different program for each possible terminal in use (and there were zillions -- often on the same system).

The BSD curses library was built on top of that. At some point, it was found lacking, and an improved library -- NCurses and terminfo -- were designed which repaired many problems with the original termcap and provided greater capabilities.

Examples of VT100 terminal capabilities are:

Clear the screen and Home the cursor
cout << "\33[2J";

Move the cursor to row, col (zero-based):
cout << "\33[" << row << ";" << col << "H";

Scroll the display up count lines:
cout << "\33[" << count << "S";

Scroll down:
cout << "\33[" << count << "T";

Insert count lines at the cursor:
cout << "\33[" << count << "L";

Delete lines:
cout << "\33[" << count << "M";

Set bold text:
cout << "\33[1m";

Set reverse text:
cout << "\33[7m";

Set normal text:
cout << "\33[0m";

Set foreground color:
cout << "\33[3" << foreground << "m";
(where 'foreground' is one of enum {black = 0, red, green, yellow, blue, magenta, cyan, white})

Set background color:
cout << "\33[4" << background << "m";

Set multiple attributes at once: bold cyan on blue background:
cout << "\33[31;44;1m";

These, and many more, of course, only work on VT100 and compatibles.

So when you see a post saying, "Hey, to clear the screen just print "\33[2J" to the screen" take it with a large grain of salt -- remember, it is a VT100/ANSI.SYS code, and is not guaranteed (or even likely) to work reliably. Instead, point said poster to things like
http://www.cplusplus.com/forum/articles/10515/

Hope this helps.
thanks very much for the detailed descriptions!
Topic archived. No new replies allowed.