Is it possible in C to output something to the console without using stdio.h, printf?

  • 2
    But why? - VladD
  • 2
    Yes - Denis
  • a "iostream.h" in C was? Or is it already borland C so implemented? - pavel
  • one
    @pavel, this is not a purely positive title, there wasn’ta C - Alex Krass

5 answers 5

stdio.h is a buffered add-in above the basic read / write I / O functions declared in unistd.h .

 #include <unistd.h> write(1, "Hallo!\n", sizeof "Hallo!\n" - 1); 

The first argument is a file descriptor — the number in the open file table of the executable program. When launched according to the standard, three descriptors are open in advance: 0 - standard input, 1 - standard output, 2 - standard error output. Some systems may have more.

fwrite from the same stdio.h . It works in a similar way, but through the same buffer as printf :

 #include <stdio.h> fwrite("Hallo!\n", sizeof "Hallo!\n" - 1, 1, stdout); 

Although it calls write , it often turns out to be faster due to buffering when writing a large amount of data to a file (when redirecting output). Of course, fwrite faster than printf , since the latter looks for format strings in the string that begin with a % sign.

fputs and puts from stdio.h print a string ending with a null byte ( '\0' ). The second one also adds the end-of-line character and outputs only to the standard output.

 #include <stdio.h> fputs("Hallo!\n", stdout); puts("Hallo!"); // выводит то же самое, что и предыдущая функция 

The speed should be like fwrite , but they differ in the method of determining the length of the string, so using them it is impossible to deduce the zero bytes. My measurements in ubuntu however show that puts is somehow much slower than fputs and almost like printf .

  • Is this way faster than printf? - kalokusatel
  • one
    @kalokusatel It seems to be faster, because printf will still call write , but it will also scan the line for format sequences like %d , etc. However, if you redirect the output to a file on disk, the buffered output will accumulate all calls to printf , etc. until the buffer is full, and output it with a single write . This will reduce the number of calls to the system, and can speed up the program. That is, it all depends on the size of the output data. - sercxjo
  • 2
    @kalokusatel: printf() prints a buffer (memory) to stdio, so it can be much faster to write() (system call) if the latter is often called with small input. If you have a question how to make printf() faster, then this is a completely different question compared to real I / O (especially disk I / O), calculations are usually quick. - jfs

In addition to POSIX write(2) and Win32 WriteConsoleW() you can mention <conio.h> functions that also allow you to output to the console :

The library functions declared in conio.h were quite different depending on the compiler. Originally implemented in Microsoft Visual C ++, various functions were tied directly to the first few DOS functions related to interrupt 21h. But the library supplied with Turbo C ++ and Borland C ++ does not use the DOS API, but instead directly accesses the video memory to display information and use BIOS interrupt signals.

 #include <conio.h> putch('A'); 

Also (depending on hardware, OS) you can display characters on the screen using direct memory manipulation, which is displayed on the video buffer. From the book "Computer Graphics Primer", written by Mitchell Waite and published in 1979 :

In memory-mapped video RAM.

The IBM VGA BIOS ( mode 13h ) mode provides similar access to video memory as a 320 × 200 pixel array with 256 colors.

Usually between the program and the video memory there are many levels of abstraction. On Linux, if X is not running (or in Ctrl + Alt + Fx virtual console), you can mmap /dev/fb0 device (Linux framebuffer just a step above working with a video card directly — the interface is provided by the kernel itself):

 fbdev = open("/dev/fb0", O_RDWR); buffer = mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbdev, 0); 

Here buffer is a byte array with the size of screensize , which allows you to draw in the console, for example, in 1600x1200 32bpp mode ( screensize = 1600*1200*32/CHAR_BIT ), in order to paint the selected pixel with bright yellow (red + green):

 buffer[i+0] = 0; // синий buffer[i+1] = 255; // зелёный buffer[i+2] = 255; // красный buffer[i+3] = 0; // прозрачность 

Here is a sample code for how to draw a square in the console using a framebuffer: How do I display a framebuffer?

  • The most interesting thing here (for me, of course) is how to recognize screensize ? - avp
  • @avp by reference the code where screensize is calculated - jfs
  • Thanks (did not guess to look -)) - avp
  • Confusing transparency - under the framebuffer something else can be displayed? - Vladimir Gamalyan
  • @VladimirGamalian: hardly. If this is not some special device, then you can simply treat it as padding. - jfs

For Windows: WriteConsole ().
For DOS - the formation of the code call INT 21 and through the transfer of control to it.

     #include <stdlib.h> /* для любой linux системы. У меня gcc (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4 */ int main() { int i = system ("ls -al"); // показать файлы текущей директории в тч скрытые return 0; } 

      Borland C ++ 3.1:

       #include <conio.h> int main() { putch('7'); return 0; }