I was looking for a way to "reset" my Unix terminal window after closing my program, and stumbled upon printf("\033c" ); which works perfectly, but I just can't understand it. I went to man console_codes and since I'm somewhat inexperienced with Unix c programming, it wasn't very helpful.
Could someone explain printf("\033c" );?
In C numbers starting with a leading zero are octal numbers. Numbers in base 8.
What it does is print the character represented by octal number 33 followed by a 'c'.
In ASCII encoding the octal number 33 is the ESC (escape) character, which is a common prefix for terminal control sequences.
With that knowledge searching for terminal control sequences we can find e.g. this VT100 control sequence reference (VT100 was an old "dumb" terminal, and is emulated by most modern terminal programs). Using the VT100 reference we find <ESC>c in the terminal setup section, where it's documented as
Reset Device <ESC>c
Reset all terminal settings to default.
The ESC character could also be printed using "\x1b" (still assuming ASCII encoding). There is no way to use decimal numbers in constant string literals, only octal and hexadecimal.
However (as noted by the comment by chux) the sequence "\x1bc" will not do the same as "\033c". That's because 0x1bc is a valid hexadecimal number, and the compiler is greedy when it parses such sequences. It will print the character represented by the value 0x1bc instead, and I have no idea what it might be (depends on locale and terminal settings I suppose, might be printed as a Unicode character).
That's an escape sequence used to reset a DEC VT100 (or compatible) terminal. Some terminals (such as Linux console) accept VT100-style escape sequences, even when they are not actually VT100s.
The \033 is the ASCII escape character, which begins these sequences. Most are followed by another special character (this is a rare exception). XTerm Control Sequences lists that, along with others that are not followed by a special character.
In ECMA-48 it is possible to use a different character for the usual case, e.g., [ for the *control sequence initiator.
Resetting a real VT100 (in contrast to a terminal emulator) does more than clear the screen, as noted in Debian Bug report logs - #60377
"reset" broken for dumb terminals, but users of terminal emulators tend to assume it is a short way to clear the screen. The standard way would be something like this:
printf("\033[H\033[J");
The ncurses FAQ Why does reset log me out? addresses that issue.
Incidentally, users of terminal emulators also get other issues with the terminal confused. The ncurses FAQ How do I get color with VT100? addresses one of those.
It clears the screen in Linux type operating systems (ubuntu, fedora etc...).
You can check here on asciitable.com, under octal 33 (decimal 27) you have ESC character.
Related
For a school project I decided to make an app. I am writing it in C, and running it on the Windows Console. I live in Greece and the program needs read and write text in Greek too. So, I have tried just plainly
printf("Καλησπέρα");
But it prints some random characters. How can I output Greek letters? And, similarly, how can I take input in Greek?
Welcome to Stack Overflow, and thank you for asking such an interesting question! I wish what you are trying to do was simple. But your programming language (C), and your execution environment (the Windows console) were both designed a long time ago, without Greek in mind. As a result, it is not easy to use them for your simple school project.
When your C program outputs bytes to stdout via printf, the Windows Console interprets those bytes as characters. It has a default interpretation, or encoding, which does not include Greek. In order for your Greek letters to appear, you need to tell Windows Console to use the correct encoding. You do this using the _setmode call, using the _O_U16TEXT parameter. This is described in the Windows _setmode documentation, as Semih Artan pointed out in the comments.
The _O_U16TEXT mode means your program must print text out in UTF-16 form. Each character is 16 bits long. That means you must represent your text as wide characters, using C syntax like L"\x039a". The L before the double quotes marks the string as having "wide characters", where each character has 16 bits instead of 8 bits. The \x in the string indicates that the next four characters are hex digits, representing the 16 bits of a wide character.
Your C program is itself a text file. The C compiler must interpret the bytes of this text file in terms of characters. When used in a simple way, the compiler will expect only ASCII-compatible byte values in the file. That includes Latin letters and digits, and simple punctuation. It does not include Greek letters. Thus you must write your Greek text by representing its bytes with ASCII substitutes.
There Greek characters Καλησπέρα are, I believe, represented in C wide character syntax as L"\x039a\x03b1\x03bb\x03b7\x03c3\x03c0\x03ad\x03c1\x03b1".
Finally, Windows Console must have access to a Greek font in order for it to display the Greek characters. I expect this is not a problem for you, because you are probably already running your computer in Greek. In any case Windows worldwide includes fonts with Greek coverage.
Plugging this Greek text into the sample program in Microsoft's _setmode documentation gives this. (Note: I have not tested this program myself.)
#include <fcntl.h>
#include <io.h>
#include <stdio.h>
int main(void) {
_setmode(_fileno(stdout), _O_U16TEXT);
wprintf(L"\x039a\x03b1\x03bb\x03b7\x03c3\x03c0\x03ad\x03c1\x03b1\n");
return 0;
}
Input is another matter. I won't attempt to go through it here. You probably have to set the mode of stdin to _O_U16TEXT. Then characters will appear as UTF-16. You may need to convert them before they are useful to your program.
Overall, to write a simple app for a school project, which reads and writes Greek, I suggest that you consider using a tool like Visual Studio to write a GUI program. These tools have more modern design, and give you access to text with Greek letters more easily.
#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).
By reading this code, I stumbled upon the following printf() statement:
// reset, hide cursor and clear screen
printf("\e[0m\e[?25l\e[2J");
I must admit that I am not a fully qualified C hacker and do not fully understand this. I tweaked around, removing the arguments, and I understand what it does (well, the comment actually says it all), but I have no idea how it's done. Also, this is something kind of hard to google for.
How does this printf() call work?
This doesn't really have anything to do with printf. The C11 standard lists escape sequences in §5.2.2, and the list consists of \a, \b, \f, \n, \r, \t and \v. As an extension, GCC considers \e to be an escape sequence which stands for the ASCII character Esc (\E may work as well, or your compiler may support neither of them. Consult the documentation for your compiler). What follows are non-portable control sequences. They are not guaranteed to work the same in all terminals, or even work at all. The best way to know is to consult the documentation for your system.
§6.4.4.4 also describes octal escape sequences. For example, \033, where 033 is 27 in decimal, and therefore the escape character in ASCII. Similarly, you can use \x1b, which is a hexadecimal escape sequence specifying the same character.
If we inspect the output of the program with od -c, it shows 033.
(✿´‿`) ~/test> ./a.out | od -c
0000000 033 [ 0 m 033 [ ? 2 5 l 033 [ 2 J
0000016
The ANSI escape sequences are interpreted by terminal emulators. C will convert the octal/hexadecimal escape sequences to the ASCII Esc character. Your compiler, as an extension, might also convert \e or \E. As requested, a brief explanation of what the control sequences are doing:
[0m: resets all the SGR attributes
[?25l: hides the cursor
[2J: from Wikipedia:
Clears part of the screen. If n is 0 (or missing), clear from cursor
to end of screen. If n is 1, clear from cursor to beginning of the
screen. If n is 2, clear entire screen ...
The printf() call is simply outputting a specific series of byte values. The "magic" is that those values are special in the terminal.
A special series of bytes starting with the ASCII "escape" character is called an "escape sequence". These were invented for serial data terminals, where the only means of communication with the terminal was by sending byte values through the serial connection. Ordinary characters are simply displayed on the terminal, but it was desirable to have a way to move the cursor, clear the screen, etc. and most terminals used escape sequences for this.
http://en.wikipedia.org/wiki/Escape_sequence
There was one particularly popular terminal called the "VT100", and most terminal emulators today operate using VT100 escape sequences.
Even today, escape sequences are useful. You can write a simple C program that will work on the terminal emulators in Linux, Mac, Windows, mobile devices, basically everywhere. When you need to do something simple like clear the screen, just outputting the proper escape sequence is the easiest way.
I just started to learn C and then want to proceed to learn C++. I am currently using a textbook and just write the examples in order to get a bit more familiar with the programming language and procedure.
Since the example that is given in the book didn't work, I tried to find other similar codes. The problem is that after compiling the code, the program itself does not show and of the symbols represented by %c. I get symbols for the numbers 33-126 but everything else is either nothing at all or just a white block...
Also, on some previous example I wanted to write °C for temperature and it couldn't display the symbol °
The example I found on the web that does not display the %c symbols is
#include <stdio.h>
#include <ctype.h>
int main()
{
int i;
i=0;
do
{
printf("%i %c \n",i,i);
i++;
}
while(i<=255);
}
Is anyone familiar with this? Why can I not get an output for %c or e.g. ° as well???
ASCII is a 7-bit character set, which means it consists of only codepoints in the range [0, 127]. For 8-bit code pages there are still 128 available codepoints with values from 128 to 255 (i.e. the high bit is set). These are sometimes called extended ASCII (although they're not related to ASCII at all) and the characters that they map to depend on the character set. An 8-bit charset is sometimes also called ANSI although it's actually a misnomer
US English Windows uses Windows-1252 code page by default, with the character ° at codepoint 0xB0. Other OSes/languages may use different character sets which have different codepoint for ° or possibly no ° symbol at all.
You have many solutions to this:
If your PC uses an 8-bit charset
Lookup the value of ° in the charset your computer is using and print it normally. For example if you're using CP437 then printf("\xF8") will work because ° is at the code point 0xF8. printf("°") also works if you save the source file in the same code page (CP437)
Or just change charset to Windows-1252/ISO 8859-1 and print '°' or '\xB0'. This can be done programmatically (using SetConsoleOutputCP on Windows and similar APIs on other OSes) or manually (by some console settings, or by running chcp 1252 in Windows cmd). The source code file still needs to be saved in the same code page
Print Unicode. This is the recommended way to do
Linux/Unix and most other modern OSes use UTF-8, so just output the correct UTF-8 string and you don't need to care about anything. However because ° is a multibyte sequence in UTF-8, you must print it as a string. That means you need to use %s instead of %c. A single char can't represent ° in UTF-8. Newer Windows 10 also supports UTF-8 as a locale so you can print the UTF-8 string directly
On older Windows you need to print the string out as UTF-16. It's a little bit tricky but not impossible
If you use "\u00B0" and it prints out successfully then it means your terminal is already using UTF-8. \u is the escape sequence for arbitrary Unicode code points
See also
The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)
Anything outside the range 33-126 isn't a visible ASCII character. 0-32 is stuff like backspace (8), "device control 2" (18), and space (32). 127 is DEL, and anything past that isn't even ASCII; who knows how your terminal will handle that.
I'm a brand-new student in programming arena so I can't grasp this program written in my book that I have been following for a few days. The program is like this:
#include "stdio.h"
main()
{
printf("\a");
}
What does this program mean? Does this program mean that we could hear a ringing bell? I can't hear any ringing bell sound!!!
ASCII character 7 is the BELL character, and it's represented in C as \a. Some terminals will produce a beep when this character is output on the terminal; nowadays, many don't. (I'm looking at you, Ubuntu.)
Back in the dark ages when ASCII was codified out of the ashes of BAUDOT, a terminal was a large chunk of iron that hammered ink onto paper, often included a paper tape punch and reader, and interpreted keystrokes to generate an asynchronous serial signal at a few hundred baud with spinning wheels and relays.
In case an operator fell asleep to the soothing noises of it hammering out text, it had an actual bell it could ring. The character coded 007 in octal, 0x07 in hex, or as \a in a C character or string constant rang the bell when received.
As terminals became smaller and implemented with few or no moving parts, the physical bell was replaced by a beeper.
Exactly what your terminal emulator (aka a Console Window in Windows, xterm or something similar in Unix) does when it is asked to display that control character is not well standardized today. It ought to make a noise or flash the window, but your mileage will vary.
Have a look at this wikipedia entry: bell character:
In the C Programming Language (created in 1972), the bell character can be placed in a string or character constant with \a ('a' stands for "alert" or "audible" and was chosen because \b was already used for backspace).
\a does in fact trigger the system chime. It's the escape sequence for the ASCII BEL character.
You'll hear a beep from your PC's internal speaker (not the external speakers or headphones you may have attached).
Strings can contain characters which are handled different from all the other characters. The most often explicit used one is '\n'. The '\n' character does not print a character in the console, instead it tells the console to start a new line. Such special characters are called non printable since they have no own visible representation in c and have to use escape sequences instead.
In the escape sequence "\a" the backslash before the a tells the compiler that the a is an identifier for a special character and will store its char-value instead of the char-value of 'a'.
The '\a' escape sequence is the audible bell character, giving this character to a console via print() should cause a beep sound. Some consoles wont beep.
Here are some special characters, the link is from a c++ reference but most should be valid for c.
\a is the C representation of the ASCII audible alert ("bell") control character.
On an old-school serial terminal, outputting that character produced a "beep" sound. Your terminal emulator may or may not implement this feature.
Apart from all the answers you've got, take into account that your program won't probably compile. Here is the fixed version:
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("\a");
return EXIT_SUCCESS;
}
The most important change is that system headers must be surronded with < and >, instead of quotes. Also, it is better to know that the main() function always returns an int (to the operating system), and that this int is coded in two constants, EXIT_SUCCESS, and EXIT_FAILURE, in the header stdlib.h
Try something simpler:
printf("hello\tworld");
printf("hello\nworld");
and see what happens.
Your example with the BELL char, as others have pointed out, probably won't work on today's toasters^H^H^H^H^H^H^H^H computers; most terminals redirect the 'bell' character to either be discarded or to flash the terminal briefly.
And believe me, you want to keep it that way for the night-coding sessions :)
The above program which you have written I have tried it in the code blocks using GNU GCC Compiler..
It was working fine..
If you want to hear a beep sound you can try it another way it will only be useful in Windows!
#include<stdio.h>
#include<windows.h>
main()
{
Beep(600,600); /* you have to enter both the values whatever you want
}
As a matter of interest this appears to work in all builds that don't have a wWinMain or WinMain entry point. wprintf(L"\a") sounds fine for Unicode builds. (Win 7 here).
The PC speaker used to depend on "speaker.drv" but that little beauty has been taken away some time back and replaced with beep.sys which is now moved into the user mode system sounds agent.
Enabling and disabling the speaker from the command prompt is also discussed here.
#include<stdio.h>
int main()
{
int i = 263;
putchar(i); // or you can directly use putchar(263);
return 0;
}
This program produces a bell sound while you are on the output screen
the problem isnt about wheter your C program compiles its fully depend your terminal settings usually they make beeps using PC speakers that comes with laptop and PCs before UEFI exist
https://en.wikipedia.org/wiki/PC_speaker
i tested it using 2 laptops one of them were bought before UEFI even a thing and other bought after UEFI become common thing
i run echo -e '\a' on both test (both linux system with pcspkr module loaded) and sure the laptop before UEFI exist is beep other laptop just silent