2

I'm trying to write a text editor for Linux that looks like MS-DOS EDIT.

However, I'm stuck because I can't figure out how to draw the thin rectangles around the editor screen and dialog box. I know the Linux dialog command can do something similar:

How can I draw rectangles like that around the screen (preferably without curses)?

MD XF
  • 7,860
  • 7
  • 40
  • 71
DEADBEEF
  • 525
  • 1
  • 5
  • 19
  • If you just want to output binary characters to the screen you can run this in python to see what each one looks like so you can choose the corners etc. `for i in range(127,256): print i,hex(i),chr(i)` – Marichyasana Apr 28 '17 at 04:57
  • Why don't you want to use curses or a derivative? It was *made* for problems like this. – jpmc26 May 04 '17 at 23:47

4 Answers4

5
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃These are box-drawing characters.      ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│They live in the U+2500-U+257F range of│
│Unicode characters.                    │
└───────────────────────────────────────┘

░▒▓▛▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▜▓▒░
░▒▓▌ The shadows are block elements, ▐▓▒░
░▒▓▌ Unicode U+2580-U+259F.          ▐▓▒░
░▒▓▙▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▟▓▒░

Once upon a time, box-drawing characters and block elements and were common in CP-437. Modern terminals likely expect UTF-8. (They don't work very well in web browsers... see here if the above text looks odd.)

There are also ANSI escapes to set the background color, foreground color, and other attributes of text displayed on a terminal. I can't demonstrate it well on Stack Overflow, though.

ephemient
  • 198,619
  • 38
  • 280
  • 391
4

The ncurses library is a good way to do what you want, although you say you want alternatives. You can use the Unicode box-drawing characters as wide characters. They include all the characters from MS-DOS code page 437.

Modern distributions should be set up to support UTF-8 by default, so this should work. (I recommend saving the source file as UTF-8 with a byte-order mark.)

#define _XOPEN_SOURCE 700

#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>

int main(void)
{
  setlocale( LC_ALL, "" );
  fputws( L"╒╩╤╣\n", stdout );

  return EXIT_SUCCESS;
}

Without curses, you can check the environment variables LINES and COLS to get the dimensions of the terminal. The control characters to print colors and such on the Linux console are in the console_codes(4) man page (and are a variant of the VT102 control codes, which are a superset of VT100, a superset of ANSI standard terminals). If you want to invoke it from a program such as gnome_terminal, check its documentation too, but it will probably implement an extension of xterm, which is an extension of VT102, etc. One that is very useful is that the form feed character '\L' will clear the screen and let you redraw it. You could also use terminfo or termcap for a more abstract and general interface, but in practical terms, nobody uses anything other than an extension of VT100 plus ANSI color any more.

Make sure your terminal font includes the line-drawing characters you want to use! DejaVu Sans Mono is an excellent monospace font, especially for its coverage of Unicode. Also, you can check that your locale is set correctly with the locale command; the locale names you see should end in something like .utf8 or UTF-8.

Davislor
  • 14,674
  • 2
  • 34
  • 49
  • UTF-8 byte order marks are superfluous and [not recommended](http://stackoverflow.com/a/2223926/1394393). MS is the primary one mucking everything up with it. – jpmc26 May 04 '17 at 23:50
  • I recommend them in this specific context, C/C++ source files. Older versions of MS Visual Studio will interpret any source file without one as encoded in the local code page, so there are real-world compilers that need one. In modern compilers, UTF-8 with BOM is the format that just works. There are some older tools that have a problem with the BOM, but those probably would have a problem with Unicode inside the file as well. – Davislor May 05 '17 at 01:05
  • As I said, "MS is the primary one mucking everything up with it." Almost everything non-MS handles it fine without one, and a good chunk of things get confused with it (or just treat it as regular characters). Logically, prepending the BOM makes no sense since UTF-8 doesn't have multiple valid byte orders. If MS wanted plain text files with an identifiable encoding, they should've proposed a standard that actually specifies the encoding, which would work for a lot of other encodings, too, instead of doing something nonsensical. – jpmc26 May 05 '17 at 01:16
  • Right, so UTF-8 BOM is sometimes what you have to use. VS 2017 will attempt to autodetect the character set, and will always succeed if it has a BOM. VS 2015 will interpret a source file as encoded in the local code page, unless it contains a BOM or you override with a command-line option. Previous versions of VS support no such command-line option; a BOM is the only way to get UTF-8 source to compile with them. Other compilers that support UTF-8 string literals will correctly read the BOM. – Davislor May 05 '17 at 01:39
2

What you're describing is using the box drawing characters present in various extended character sets. The characters available depend at least on the platform and terminal emulation.

Given your question is tagged with Linux, the easiest method would be to use the ncurses library. Why would you prefer not to use it and have to reinvent that wheel?

If you can expect at least VT100 emulation (reasonable) then you can use the basic line drawing, but higher levels have more characters.

It's a bit old, but have a look at the window sample code here:

You may also want to look into the Xterm escape characters (expands the VT100 set):

gavinb
  • 19,278
  • 3
  • 45
  • 60
0

You're looking for box-drawing characters. Here's a complete table.

Assuming your system has a Unicode font installed, which most modern distros do, you could print those to your terminal like this:

#include <wchar.h>
#include <locale.h>
...
    setlocale(LC_ALL,"en_US.UTF-8");
    wprintf(L"\u250C\u2500\u2510\n");    // ┏━┓
    wprintf(L"\u2502 \u2502\n");         // │   │
    wprintf(L"\u2514\u2500\u2518\n");    // └━─┘
MD XF
  • 7,860
  • 7
  • 40
  • 71