ncurses.h, wprintw doesn't work, even after refresh - c

I'm using the library ncurses, and when I try to call wprintw(), and then do a wrefresh on the right window, it doesn't print anything.
#include <stdio.h>
#include <stdlib.h>
#include <ncurses.h>
int main()
{
WINDOW *winTest; //The window
int rows, cols; //Rows and colums in the terminal
initscr(); //Starting NCurses
raw(); //Calling 'getch()' doesn't wait for '\n'
noecho(); //Doesn't print what's written by user
curs_set(0); //Doesn't display the cursor
getmaxyx(stdscr, rows, cols); //How many rows and colums in stdscr (the terminal)
winTest = newwin(10, 10, rows/2, cols/2); //Creates a square WINDOW at the center of the terminal
mvwprintw(winTest, 0, 0, "Test"); //Prints "Test" on the created window
wrefresh(winTest); //Refreshes so what's done is displayed
getch(); //Pause
delwin(winTest); //Free the memory for winTest
endwin(); //Ends NCurses
return 0;
}
When I execute this, nothing is displayed.
I'm on Ubuntu 14.04 LTS, I compile with gcc:
gcc -g -Wall -Werror -Wpedantic -Wextra -Wformat -o test.exe test.c -lncurses
and I execute in the gnome-terminal.

As explained here, you should replace:
getch();
by:
wgetch(winTest);

I replaced the second pause, getch() with my own pause function: scanf("%*s"); and then it displayed test in the middle like it was supposed to. I think what was happening is it went through both pauses in one go so that you never saw the "Test" because it was deleted as fast as it was created. – Tony Ruth
Thanks to Tony Ruth, who answered my question. Even if I still don't understand why getch() erases what's written, replacing it with scanf("%*s") works fine !
PS: Don't know how to tell this issue is solved :/
EDIT : You can also call 'wgetch(aWindow)' on whatever window, and every windows will be corectly displayed :) (Thank to Ruud, who told it)

Related

In linux program cannot erase utf-8 character completely using backspace

I have a C program which waits for user's input
#include <stdio.h>
int main()
{
getchar();
return 0;
}
Now I run it and input some Chinese characters like 测试测试. Then now I click backspace, I found I cannot erase these characters completely(some blank remained)
I found termios has a flag setting IUTF8, but why it doesn't work?
UPDATE ON 2022/12/31:
I am trying to describe my question more detailed, I have a program like this
Now I run it and enter some Chinese characters(without Enter key)
Then I keep clicking Backspace key(until nothing can be erased any more), but half of the content still display on my screen. It's so abnormal, how can I make the erase perform well?
I know it is a stupid question for you. I just want to make it more comfortable when typing some UTF8 characters(like Chinese characters).
I found the shell can handle this well, how can I do to make my program perform the same?
By the way, this is my locale output
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC=zh_CN.UTF-8
LC_TIME=zh_CN.UTF-8
LC_COLLATE="en_US.UTF-8"
LC_MONETARY=zh_CN.UTF-8
LC_MESSAGES="en_US.UTF-8"
LC_PAPER=zh_CN.UTF-8
LC_NAME=zh_CN.UTF-8
LC_ADDRESS=zh_CN.UTF-8
LC_TELEPHONE=zh_CN.UTF-8
LC_MEASUREMENT=zh_CN.UTF-8
LC_IDENTIFICATION=zh_CN.UTF-8
LC_ALL=
Use GNU readline to provide a shell-like interface, with Tab autocompletion, correct input handling, et cetera.
To compile the following example program, make sure you have the libreadline-dev package installed. The readline library needed to run the program will already be installed, because so many applications that are installed by default require it already.
// SPDX-License-Identifier: CC0-1.0
// Compile using
// gcc -Wall -O2 $(pkg-config --cflags readline) example.c $(pkg-config --libs readline) -o example
#define _GNU_SOURCE
#include <stdlib.h>
#include <locale.h>
#include <readline/readline.h>
#include <readline/history.h>
#include <stdio.h>
int main(void)
{
char *line;
setlocale(LC_ALL, "");
while (1) {
line = readline(NULL); // No prompt
// Input line is in 'line'; exit if end of input or empty line.
if (!line || *line == '\0')
break;
// Do something with 'line'
// Discard the dynamically allocated line
free(line);
}
return 0;
}
When using the GNU readline library, the library takes over the standard input, and handles character deletion (and many other things) at the terminal (termios) level. It works absolutely fine with file and pipe inputs as well, and is what e.g. bash shell uses for interactive input.

getmaxyx always returns 1 and 1 in pdcurses instead of the number of rows and columns

#include <curses.h>
int main() {
initscr();
int row, col;
getmaxyx(stdscr, row, col);
printw("%d %d", row, col);
getch();
}
If I compile this code with ncurses (gcc -lncurses test.c), I get, as expected, the number of rows and columns of the terminal (31 and 88 in my case), but if I compile it with pdcurses (gcc -lpdcurses -lSDL test.c) I get 1 and 1 as the output. Why is that? Am I missing something? Resizing the terminal with resize_term(100, 100); does not change the output
For some reasons pdcurses doesn't like ncurses curses.h, changing the header to xcurses/curses.h solves the issue for me

Function printf() to print backspace problem

There are two programs and they get different results, but I don't understand why.
Here is the first:
int main()
{
printf("12345");
fflush(stdout);
printf("\b\b");
fflush(stdout);
return 0;
}
The result is: 123.
Then the second:
int main()
{
printf("12345");
fflush(stdout);
sleep(1);
printf("\b\b");
fflush(stdout);
return 0;
}
but the result is: 12345.
Why does the sleep call make the second result different when I expect a "123" result?
The code was running in the CLion.
and My OS is macOS, if it matters.
Depending on the Terminal, '\b' might "erase" a character or only move the cursor to the left. To have a foolproof solution, use:
#include <unistd.h>
#include <stdio.h>
int main(void)
{
printf("12345");
fflush(stdout);
sleep(1);
printf("\b\b \b\b");
fflush(stdout);
}
Your code first displays "12345" and then displays "123". Without the sleep, the "12345" is displayed for too little time to be visible. With the sleep, you can see the "12345" for about a second before the "4" and "5" are erased.
With the original code (called bs97, compiled from bs97.c), and with my command line prompt Osiris JL:, I get the output:
Osiris JL: bs97
123Osiris JL:
Note that the new prompt has overwritten the 45. You can see that if you add putchar('\n'); after the second fflush(). (I added void to int main(void) to avoid compilation warnings (errors) with my default compilation options.)
Osiris JL: make bs97 && bs97
gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes bs97.c -o bs97
12345
Osiris JL:
This time, the 4 and the 5 are still visible.
Simply using backspace does not erase the content that was previously there; it positions the write position on screen back one place, that's all. If you want to erase what was there, you need to output printf("\b \b\b \b") to go back, output a space, and go back again — repeated twice. Or you could use printf("\b\b "), but that would leave the write position after the two spaces; or you could use printf("\b\b \b\b") to leave the write position after the 3. And there are other variations on this theme.
With the second program with the sleep, I get similar behaviour, except that the 12345 is on display while the program sleeps.
I'm testing on a Mac running macOS 10.14 Mojave, using a home-built GCC 8.2.0 or the clang compiler from XCode 10.0.

Simple C code prints nothing to terminal

I ran a 4 line code and it compiled and linked without a hitch, but it refuses to print anything
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
char* a = "book";
printf("%s\n", a);
return 0;
}
After compiling it and running the executable, nothing happens.
No error in the code.
Just write getch(); or getchar() before return 0;
to holding the output screen.
getch() or getchar() will hold the ouput screen for getting the user's input.
Works fine for me.
You've tagged this with terminal; if you are running it from the terminal, you should see some output, in my experience.
If you are running from an IDE,
keep the window open using Kapil K.'s answer;
keep the window open using an IDE setting, if there is one; or
find out where your IDE is putting the executable file, and run that from a terminal.

No output from ncurses without second getch

I am having a similar problem to Ncurses No Output.
Just I am having a getch call before exiting.
I don't see any output when I don't add a second getch call
before outputting anything. The following is a collection of
all relevant code parts copied together in one routine
exhibiting the same problem as my complete program.
So some calls look superfluous but I find those necessary
in the local context.
#include <glib.h>
#include <stdlib.h>
#define bool ncbool
#include <ncurses.h>
#undef bool
gint32 main ( gint32 argc, gchar * argv [] )
{
initscr ();
keypad ( stdscr, FALSE );
nonl ();
cbreak ();
nodelay ( stdscr, FALSE );
noecho ();
/*
gint zch_extra;
zch_extra = getch ();
*/
WINDOW* w;
w = newwin ( 5, 10, 3, 3 );
box ( w, 0, 0 );
wnoutrefresh ( w );
mvwaddstr ( w, 1, 1, "huhu" );
wnoutrefresh ( w );
doupdate ();
mvwaddstr ( w, 2, 1, "<cont>" );
wrefresh ( w );
gint zch;
zch = getch ();
clear ();
refresh ();
nl ();
nocbreak ();
echo ();
endwin ();
return 1;
}
I only see output when I add the extra getch commented out in the code.
Compilation commands:
gcc -I /usr/include/ncurses -I /home/mkiever/include -I/usr/include/glib-2.0 -I/usr/lib/i386-linux-gnu/glib-2.0/include -ansi -ggdb -c -o main.o main.c
gcc -o test main.o -lncurses `pkg-config --libs glib-2.0`
Platform (uname -a): Linux Pirx 3.16.0-4-686-pae #1 SMP Debian 3.16.7-ckt11-1 (2015-05-24) i686 GNU/Linux
What am I doing wrong? I guess, it's my combination of different refresh calls, but I don't have a clue where exactly the problem is.
Thanks for taking a look.
curses starts up wanting to clear the screen stdscr (as noted in the manual page for initscr):
initscr also causes the
first call to refresh(3x) to clear the screen.
Doing that requires a refresh, sometime after the call to initscr. getch does a refresh of stdscr. In the non-working case, the program creates, modifies and refreshes the other window, but when you call getch, curses refreshes stdscr (again, in the manual), overwriting that window.
It does those steps internally, no need to show the result until the program requests input via getch.

Resources