C: output differences between Windows console and Linux bash

I am trying to find a way to make my code compatible for UNIX and Windows systems. By default, the Windows console has an 80 character width. In Linux, the terminal width is greater than 80. Then, when I am trying to run my code #1 below in Linux it works fine. At the end of the "column" #80 it breaks the line. For Windows, only #2 code works (line printf("\n"); has been removed). This is due to the fact that printing a character at column #80, the Windows console goes automatically to the next line without asking for it. Is there any C standard way to solve this? Thanks guys.

Let's see, code #1:

for (row=0; row<25; row++)
    {
        for(columns=0; columns<80; columns++)
        {
                printf("%c", matrix[row][columns]);     
        }
        printf("\n");  
     }

and code #2:

for (row=0; row<25; row++)
    {
        for(columns=0; columns<80; columns++)
        {
                printf("%c", matrix[row][columns]);     
        }
     }

EDIT: The code is supposed to print a 2D array of [25][80]- here's what is displaying: display

2 answers

  • answered 2018-05-18 11:57 Basile Starynkevitch

    The C11 standard (check by reading n1570) does not mention terminals, but only standard streams (notably stdout, see FILE* and <stdio.h>). So it makes no sense to speak of a standard function dealing with terminals (you can program some embedded system in standard C, and it does not have any terminal, even any terminal emulator).

    On Linux, you might use ncurses (and AFAIK, it has been ported to Windows). It is free software, but outside of the C standard. Probably its curses API is some Unix standard (it was in SVR4 and older BSDs, even in SunOS4 in early 1990s). You could also use other libraries (e.g. GNU readline).

    See (for Linux) termios(3) & stty(1) & the tty demystified. Terminal emulators are tricky and complex (on all operating systems, including Linux and Windows and MacOSX and Android, because they are emulating terminals like the famous VT100 which were complex peripherals). See also ANSI escape codes.

    You don't always have any kind of window : most computers in datacenters don't have any screen or keyboard and don't use any display server program. And they could run still Windows and use cmd.exe (which is a command interpreter, not a terminal emulator). However, most datacenter computers are running Linux.

    The system function is part of the C standard and could accept commands wider than 80 characters. What commands it is accepting is not specified by C11. On Unix, it runs a /bin/sh -c and could accept quite long commands (e.g. thousands of bytes), see system(3). That process might not run in a terminal emulator (if your program didn't). On Windows (which I don't know and don't use) system is rumored to use cmd.exe. I guess it is capable of running some commands of two hundreds bytes. I leave you to check that.

    The standard output of your program could go (on Linux or Windows or other OSes) to some weird device, perhaps a braille terminal (like this) which has a limited width (e.g. 40 braille characters) and only a single line. You won't be able to "display" your 25x80 screen on it. Your stdout could also go (thru redirection) to some smart phone, some pipe, some socket, some file etc... In many cases it won't be a terminal emulator so stdout won't have any meaningful notion of "width".

    On Linux, you could use isatty(3) (and perhaps fstat(2)) to test if STDOUT_FILENO is a terminal (emulator). See also tty(4).

  • answered 2018-05-18 12:09 Serge Ballesta

    No. There is no standard way to solve that at the C level, simply because C does not care for displays. It only provides the programmer a way to send text to an output system provided by the environment. The way everything is interpreted is beyond the language.

    What happens here is that on a standard Windows console (not cmd.exe which is a command interpretor in the sense of bash), when a character is displayed on last position on a line, the cursor immediately goes next line, while on a standard Linux terminal (the xterm family), the cursor remains on same position until a new character arrives. But it is possible to write a alternative Windows application that will behave the same as xterm(*) and host a CMD.exe interpretor, and it is equally possible to write a Linux terminal emulator that behaves as a Windows console does.

    All that just means that even OS recognition will not be enough. The only foolproof way is to ensure that the size of the window is strictly greater than 80 is you want to safely display lines of 80 characters.


    (*) For example ConEmu is an open source console alternative for Windows mainly targetted at proper UTF8 processing. I do not know how it processes display on last column, but as it is open source, you can (easily?) modify it to behave as xterm does.