
Question:
I'm trying to get a character from the keyboard using curses.h. This is my source (get_char_example.c):
#include <curses.h>
#include <stdio.h>
int main(void)
{
char ch;
printf("Enter a character: ");
ch = getch();
printf("\nIts ASCII code is %d\n", ch);
return 0;
}
I use the following command to compile:
gcc get_char_example.c -o get_char_example
And I get the following error:
/tmp/ccjaXwRU.o: In function `main':
get_char_example.c:(.text+0x1c): undefined reference to `stdscr'
get_char_example.c:(.text+0x24): undefined reference to `wgetch'
collect2: error: ld returned 1 exit status
using: gcc (GCC) 7.2.0 Arch Linux 4.13.9-1-ARCH
Thanks in advance!
Answer1:It is a linker error (see <a href="https://stackoverflow.com/questions/1513417/why-is-curses-on-linux-giving-me-following-error" rel="nofollow">this</a>, nearly a duplicate). ncurses
is generally known to <a href="https://www.freedesktop.org/wiki/Software/pkg-config/" rel="nofollow">pkg-config</a> (which gives more dependencies, when required), so try to compile with:
gcc -Wall -Wextra -g \
$(pkg-config --cflags ncurses) \
get_char_example.c \
$(pkg-config --libs ncurses)
<sup>You want to <a href="https://gcc.gnu.org/onlinedocs/gcc/Invoking-GCC.html" rel="nofollow">Invoke GCC</a> with all warnings and debug info; you would <a href="https://sourceware.org/gdb/current/onlinedocs/gdb/" rel="nofollow">use GDB</a>, perhaps under emacs
or with ddd
, for debugging.</sup>
Even better, use some <a href="https://en.wikipedia.org/wiki/Build_automation" rel="nofollow">build automation</a> tool (like <a href="https://www.gnu.org/software/make" rel="nofollow">make
</a> or ninja
). With <a href="https://www.gnu.org/software/make/manual/html_node/index.html" rel="nofollow">GNU make
</a> take inspiration from <a href="https://stackoverflow.com/a/20146082/841108" rel="nofollow">this</a> to write your <a href="https://en.wikipedia.org/wiki/Makefile" rel="nofollow">Makefile
</a> (where <kbd>tab</kbd>-s are significant).
On my Debian Sid, pkg-config --cflags ncurses
gives -D_GNU_SOURCE -D_DEFAULT_SOURCE
and pkg-config --libs ncurses
gives -lncurses -ltinfo
, so simply linking with -lncurses
is <em>not</em> enough (and that is why <a href="https://stackoverflow.com/questions/1513417/why-is-curses-on-linux-giving-me-following-error" rel="nofollow">this</a> is not exactly a duplicate today in November 2017; a few years ago linking with simply -lncurses
was enough, today it is not).
Use pkg-config --list-all
to find all the packages and libraries known to <a href="https://www.freedesktop.org/wiki/Software/pkg-config/" rel="nofollow">pkg-config</a>; when developing <em>your</em> libraries consider also providing some .pc
file for it.
BTW, your program should start by initializing with initscr
and use printw
; Read <a href="http://www.tldp.org/HOWTO/NCURSES-Programming-HOWTO/" rel="nofollow">Ncurses-programming-HowTo</a> even if it is a bit old.
Notice also that using ASCII in the 21<sup>st</sup> century is obsolete. <strong>Programs</strong> and computers <strong>use <a href="http://utf8everywhere.org/" rel="nofollow">UTF-8 everywhere</a></strong>, and this has profound consequences you should be aware of (since an <a href="https://en.wikipedia.org/wiki/UTF-8" rel="nofollow">UTF-8</a> character can span <em>several</em> bytes). My French keyboard has keys for ²
, §
, €
and é
(even with American keyboards your could paste them) and none of these are in ASCII. Consider also using some UTF-8 library like <a href="https://www.gnu.org/software/libunistring/manual/libunistring.html" rel="nofollow">libunistring</a>.