ncurses.h extended characters not displaying properly in c - c

I am trying to pretty up my program by using ncurses extended characters. However, some of them show up as the question mark in a box: ⍰. This happens when I try functions such as:
addch(ACS_S1);
addch(ACS_LANTERN);
addch(ACS_S3);
And so on. Any help would be appreciated.
#include <ncurses.h>
int main()
{
initscr();
addch(ACS_S1);
addch(ACS_S3);
addch(ACS_S7);
addch(ACS_S9);
addch(ACS_LANTERN);
refresh();
getch();
endwin();
return 0;
}
edit: I forgot to add the code example. So I added it this time
edit: I am using Ubuntu to compile my code

You forgot to tell ncurses what the locale is (and if you did not compile/link with ncursesw, there are still some limitations):
The library uses the locale which the calling program has initialized.
That is normally done with setlocale:
setlocale(LC_ALL, "");
If the locale is not initialized, the library assumes that characters
are printable as in ISO-8859-1, to work with certain legacy programs.
You should initialize the locale and not rely on specific details of
the library when the locale has not been setup.

Related

Print long unicode in ncurses

I need to print some unicode characters for my game on terminal, some like this, \U0001F0A1, and my code
#include <curses.h>
#include <locale.h>
int main(){
setlocale(LC_ALL, "");
initscr();
printw("\U0001F0A1");
getch();
endwin();
return 0;
}
and all it print out is blank screen, but when i tried with printf, it can print a card out normally.
The likely problem is this: ncurses uses wcwidth to determine the width of the character, and printf does not check. The locale information on your computer is too old to give proper results.
Checking with my Debian testing, this works (using the sample program given in the question, compiling/linking with ncursesw) - see screenshot:
According to fileformat-info, this comes from Unicode 6.0 (2010). Depending on what system you are using, e.g., Debian or Ubuntu, that may be "recent".
ncurses requires correct wcwidth locale information while printf does not use the wcwidth-information. If your locale information is too old, wcwidth returns a negative value, telling ncurses that the character is nonprinting. In that case, ncurses will display a blank.

Why does mingw-gcc allow getch() to be used unconditionally?

I recently started porting a TON of my C programs to a Windows environment, from my previous Linux development PC. I noticed something a bit off about mingw's Windows GCC implementation.
In Windows, I found a lovely function called getch. It's easy, it's immediate... and it's also non-standard.
I'd like to focus of the "non-standard" part of it. Specifically, I want to know why mingw-gcc allows me to use it, without using anything but the standard libraries.
Assume we have a program that prints "Hello, World!", a NL and CR, and then waits for a key and a return:
#include <stdio.h>
int main(void)
{
char str[14] = "Hello, World!"; //13 characters and a terminator
printf("%s\n\r", str);
scanf("%c");
return 0;
}
Now, let's change a bit of that program to use getch:
#include <stdio.h>
int main(void)
{
char str[14] = "Hello, World!"; //Again, 13 characters and a terminator
printf("%s\n\r", str);
getch(); //See? now it uses getch.
return 0;
}
The interesting part is, Isn't getch a call made by the conio.h library for old DOS/Win32 environments? The compiler doesn't even give a warning. Why does this work?
Here's something I find even a bit more unsettling:
int main(void) //literally NOTHING included
{
getch();
return 0;
}
What on earth? I know for a fact that getch does not exist on Linux environments (natively, anyways). So, where is the compiler getting this call from?
My best guess (please correct me if I am wrong) is that the decision to link whatever has getch is made at link time, not compile time.
In any case, this seems a little odd to me. Why does an implementation of GCC automatically include clearly non-standard capability on Windows?
The compilation step works (though it should produce a warning) because, traditionally, C allows you to call functions that haven't been declared, provided that they return an int which getch() does.
The linking step works because the C runtime library that MinGW uses is a single library, i.e., it provides all the Visual C runtime library functions, including the non-standard ones. MinGW presumably links with it by default because (apart from very rare edge cases) it is always needed, even if all you want is a main() function that does nothing. :-)
It should also be mentioned that the library in question does not officially support third-party use, except by applications built in Visual Studio 6. The more modern runtimes have deprecated getch in favour of the equivalent but standards compliant _getch, but VS6 predates that change.
The compile step will probably 'work' because compilers (at least older versions of compilers — we know that Visual Studio is not up to date with the latest C standards) will assume the return type and the parameters are all int.
The link step will need the appropriate library linked in.

alternative to the fscanf()/vscanf() functions family for using an alternative validation key or how to create a custom language layout?

I am rather knew in C. And the only way I know for setting a variable from stdin is by using thefscanf()/vscanf()functions family.
DOS operating systems are seeing a resurgence in the embedded market. The device which I am using is programmatically compatible with DOS and use a NEC V30Mx which feature the 80286 instruction set.
The problem is the built-in keyboard doesn’t feature the enter key and instead use the EXE key which enter the 0x1C00 key code (Alt enter).
So when I write a program like this :
#include <stdio.h>
#include <dir.h>
#include <dos.h>
int main(void) {
int res, number = 0;
printf("int value?");
res = scanf("%d", &number);
printf("The value is %d", number);
return;
}
scanf()is called and "int value?" is displayed on the screen. I can write numbers and upercase letters. but I can’t validate the output since nothing feature the 0x1C0D key code, and the EXE key use a different keycode.
Of course C has no knowledge of keyboard but the C standard library binaries look for the 0x1C0D key code for entering a\n.
So is there an alternative to thefscanf()/vscanf()functions family which is part of the C standard library?
Update :
I thought most C standard libraries under dos use software implementation for doing this.
I saw a DOS call for reading files and of course, using the number 0 cause to read from stdin.
So I assembled this example, loaded it on the calculator and find myself surprised the manufacturer preferred handling the issue in it’s built-in software rather than fixing the OS... :-( (I got the the same previous result)
Update
I didn’t thought about it but thanks to the comments, I forgot keyboard languages do key code remapping.
So, creating a custom mapping for the qwerty keyboard would be an another way to solve the problem.
The problem is scanf does not read past the bytes present in stdin that represent the EXE key.
Can you investigate to see what actual characters are read by getchar() when you press the EXE key, and write a function hasexe() that skips these if present. Call this function before or after the scanf().
Also check scanf() return value and check for EOF.
The only way to solve such a problem with standard C library is to use getchar() (or fgetc() on stdin) to get a character one at a time, detect the EXE key yourself, NUL terminate the string and pass it to sscanf().

GNU/Linux replacements for Turbo C functions `clrscr` and `cprintf`

I just moved to Linux for just a month. I've used Borland Turbo C for C programming but some of these functions do not work in GNU/Linux, so looking for help.
These are some of the functions I would like to replace:
- gotoxy
- cprintf
- clrscr
- initgraph/graphics.h
I would appreciate some code examples showing how to use any replacements.
In linux, you can use the ncurses library to use the terminal as a text buffer: move the cursor around, and write text. It can also draw windows and other hi-level widgets.
For gotoxy see move and wmove from ncurses (link).
For cprintf see printw.
You can clear the screen simply with clear().
In ncurses you also need to refresh the screen with refresh() after printw and clear().
Example program, which uses all the mentioned functions in ncurses:
#include <curses.h>
int main(int argc, char *argv[])
{
initscr();
clear();
move(15, 20);
printw("Test program: %s", argv[0]);
refresh();
getch();
endwin();
return 0;
}
Compile in gcc with: gcc program.c -lcurses
As for graphics, you have to choose a particular library.
If you need a similar experience as the low-level graphics.h, you are probably looking for directfb or svgalib.
If you want to render graphics in a window, SDL will be helpful.
The functions you refer to are part of Borland's proprietary library for console applications. You want to read about ncurses.
About graphics.h
Regarding using graphics.h in Linux is an easy task. I had the same problem a week ago. Well you can goggle with search term "graphics.h in Linux", and you will get many links and here is one.
http://www.rajivnair.in/2007/07/graphicsh-in-gnulinux.html.
About Clear Screen
For that, you have many options.
And the one is,
using system("clear") but it needs stdlib.h and it is slower in performance.
Here two links for you...
How do I clear the console in BOTH Windows and Linux using C++
cprogramming.com
About gotoxy
As mentioned in Michał Trybus's Answer.
About cprintf
I Referred many links, but not getting the simple answers. Me too waiting for the answers for this.
But,In my experience whenever I want the output to be in some colored format , I will use graphics.h, though it is not required.That's why I doesn't had this question in my mind ever before.
You may find this link useful...
codeguru.com
About getch
I think you may already know about this. Instead of getch() in conio.h(not in ansi standard), you can use getchar() in stdio.h.
Just, I was answering the same questions in another thread:
void gotoxy(int x, int y) {
printf("%c[%d;%df",0x1B, y, x);
}
void clrscr(void) {
fprintf(stdout, "\033[2J\033[0;0f");
fflush(stdout);
}
void textcolor(int attr, int fg, int bg) {
printf("%c[%d;%d;%dm", 0x1B, attr, fg + 30, bg + 40);
}
Easy way to do it!

Equivalent to Windows getch() for Mac/Linux crashes

I am using getch() and my app crashes instantly. Including when doing:
int main()
{
getch();
}
I can't find the link but supposedly the problem is that it needs to turn off buffering or something strange along those lines, and I still want cout to work along with cross platform code.
I was told to use std::cin.get(), but I'd like the app to quit when a key is pressed, not when the user typed in a letter or number then press enter to quit.
Is there any function for this? The code must work under Mac (my os) and Windows.
Linking/compiling is not an issue; I include <curses.h> and link with -lcurses in XCode, while Windows uses <conio.h>.
Have you looked in <curses.h> to see what the getch() function does?
Hint: OSX and Linux are not the same as Windows.
Specifically, as a macro in <curses.h>, we find:
#define getch() wgetch(stdscr)
Now, there appears, on your system, to be an actual function getch() in the curses library, but it expects stdscr to be set up, and that is done by the curses initialization functions (initscr() and relatives), and that is signally not done by your code. So, your code is invoking undefined behaviour by calling curses routines before the correct initialization is done, leading to the crash.
(Good hint from dmckee - it helped get the link line out of acidzombie24, which was important.)
To get to a point where a single key-stroke can be read and the program terminated cleanly, you have to do a good deal of work on Unix (OSX, Linux). You would have to trap the initial state of the terminal, arrange for an atexit() function - or some similar mechanism - to restore the state of the terminal, change the terminal from cooked mode into raw mode, then invoke a function to read a character (possibly just read(0, &c, 1)), and do your exit. There might be other ways to do it - but it certainly will involve some setup and teardown operations.
One book that might help is Advanced Unix Programming, 2nd Edn by Mark Rochkind; it covers terminal handling at the level needed. Alternatively, you can use <curses.h> properly - that will be simpler than a roll-your-own solution, and probably more reliable.
You have not exhibited a
#include <stdio.h>
or
#include <curses.h>
or similar line. Are you sure that you are linking against a library that includes getch()?
Use the cin.get() function for example:
#include <iostream>
using namespace std;
int main()
{
char input = cin.get();
cout << "You Pressed: " << input;
}
The program would then wait for you to press a key.
Once you have, the key you pressed would be printed to the screen.
The getch function is not available on Unix-like systems, but you can replace it with console commands through your compiler with the system function.
Usage:
In Windows you can use system("pause");
In Unix-like systems (such as OSX) you can use system("read -n1 -p ' ' key");
Note: system is declared in <stdlib.h>.

Resources