top and bottom half block character in ncurses - c

I'm building a ncurses program in c and i want to get the upper and lower half block characters (U+2580 and U+2584 for example) (▀) for graphics on small terminals (i normally use double space and inverted double space). I've tried a lot of different ways, but none of them worked. I also tried urxvt st and xterm with absolutely no success. For example:
#include <locale.h>
#include <ncurses.h>
int main (int argc, char *argv[]) {
setlocale(LC_ALL, "");
initscr();
add_wch(L"\u2584");
refresh();
getch();
endwin();
}
Also, i would be very interested if there is any other way of displaying graphics in a terminal, like some tiny dots i've seen.
EDIT: Also, when i paste the character to the terminal it shows it fine but when i use printf it shows nothing. why is that?

The statement
add_wch(L"\u2584");
won't work for any terminal because the parameter is the wrong datatype. add_wch expects a cchar_t datatype, while you have provided a string of wchar_t (you'll get better results with waddwstr).

Related

NCurses: reading input from other terminal misses keys

I am redirecting the ncurses hmi to a different, already existing terminal. While the output part works fine (and is therefore not shown here), the input misses keys which then appear in the terminal as though they had been entered without ncurses.
#include <stdio.h>
#include <curses.h>
int main(int argc, char *argv[])
{
FILE *fd = fopen(argv[1], "r+");
SCREEN *scr = newterm(nullptr, fd, fd);
set_term(scr);
noecho();
keypad(stdscr, TRUE);
while (true) {
int ch = wgetch(stdscr);
printf("In %d\r\n", ch);
}
return 0;
}
I create two terminals on Ubuntu and get the name of one (let's call it the 'curses-terminal') using 'tty'. This name is then used as argument when starting the above in the other terminal.
When typing in the curses-terminal, I expect the codes of the keys to appear in the other terminal without seeing anything in the curses-terminal.
Instead, I see some of the characters diffuse into the curses-terminal without their code being displayed in the other one. This happens with normal characters when typing more quickly, but it happens especially with arrow keys and ALT- combinations, where the error rate is >> 50%.
Are there any settings which I have forgotten?
Using G.M.'s hint, I was able to reliably get all input.
Run
tail -f /dev/null
in the curses-terminal before attaching the ncurses app.
Should you be tempted (like me) though to send this command from within your app after fopen, you may end up frustrated.

How can i clearscreen in a while loop, in C programming? [duplicate]

I want to know: how to clean screen on an UNIX-based system? I searched on the Internet, but I've just found how to do it on Windows: system("CLS")
I don't want exactly to clean cpmpletely the screen, but I want to open a "new page", such as in the NANO and VI editors. Thanks
Maybe you can make use of escape codes
#include <stdio.h>
#define clear() printf("\033[H\033[J")
int main(void)
{
clear();
return 0;
}
But keep in mind that this method is not compatible with all terminals
You can use the following code which use termcap for clear screen.
(don't forget to link with the library)
#include <stdio.h>
#include <stdlib.h>
#include <termcap.h>
void clear_screen()
{
char buf[1024];
char *str;
tgetent(buf, getenv("TERM"));
str = tgetstr("cl", NULL);
fputs(str, stdout);
}
#include <stdlib.h>
int main(void)
{
system("clear");
}
Portable UNIX code should be using the terminfo database for all cursor and screen manipulation. This is what libraries like curses uses to achieve its effects like windowing and so forth.
The terminfo database maintains a list of capabailities (like clear which is what you would use to clear the screen and send the cursor to the top). It maintains such capabilities for a wide range of devices so that you don't have to worry about whether you're using a Linux console or a (very dated) VT52 terminal.
As to how you get the character streams for certain operations, you can choose the time-honored but rather horrible method of just using system to do it:
system ("tput clear");
Or you can capture the output of that command to a buffer so later use involve only outputting the characters rather than re-running the command:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
static char scrTxtCls[20]; static size_t scrSzCls;
// Do this once.
FILE *fp = popen ("tput clear", "r");
scrSzCls = fread (scrTxtCls, 1, sizeof(scrTxtCls), fp);
pclose (fp);
if (scrSzCls == sizeof(scrTxtCls)) {
actIntelligently ("you may want to increase buffer size");
}
// Do this whenever you want to clear the screen.
write (1, cls, clssz);
Or, you can link with ncurses and use its API to get whatever capabilities you want, though this might drag in quite a bit of stuff for something as simple as clearing the screen. Still, it's an option to be considered seriously since it gives you a lot more flexibility.
It is usually not a matter of just clearing the screen, but of making a terminal aware application.
You should use the ncurses library and read the NCURSES programming HowTo
(You could perhaps use some ANSI escape codes as David RF answered, but I don't think it is a good idea)
You can achieve this using CSI sequences:
#include <stdio.h>
int main()
{
printf("\x1b[H\x1b[J");
}
What does \x1b[H?
Actually it is the same as \x1b[1;1;H, it means that it will move the cursor to row 1 and column 1.
What does \x1b[J a.k.a \x1b[0;J?
If n is 0 or missing, it will clear from cursor to end of screen.
Source: https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_sequences
Just use #include<stdlib.h> after #include<stdio.h>.
Then you can use the command system("clear");after main() {
i.e:
#include<stdio.h>
#include<stdlib.h>
int main()
{
system("clear");
After these commands you can continue with your program.
Hope this helps :)
To clear the screen using termcaps, use this :
write(1, tgetstr("cl", 0), strlen(tgetstr("cl", 0)));
Use system("clear"); with header #include <stdlib.h> (for C Language) or #include <cstdlib> (for C++).
This code is for clear screen with reset scrollbar position in terminal style windows
#include <iostream>
int main(){
std::cout << "\033c";
return 0;
}

How to use getch() in a loop (nCurses)

This is my first time using ncurses library. So, I wanted to use getch() to get a character as it is typed by the user (without pressing return every time). However, when I run this code:
#include <pthread.h>
#include <stdio.h>
#include <curses.h>
void *userInput() {
char c;
while((c = getch()) != '~') {
printf("%c\n",c);
}
pthread_exit(NULL);
}
int main() {
cbreak();
pthread_t threads[4];
pthread_create(&threads[0], NULL, userInput, NULL);
pthread_exit(NULL);
}
It printf lots of '?'s without getting any input. Could anyone please help me understand whats wrong?
Thank you.
EDIT: removed dead code.
There are at least three problems with the program:
getch will always return an error because you did not initialize the screen with initscr or newterm. Likewise, the cbreak call does nothing except return an error.
even if you initialized the screen, calling getch with multiple threads will not work predictably because it is not thread-safe. It's an FAQ: Why does (fill in the blank) happen when I use two threads?
the printf does something, but mixing stdio (printf) and curses does not work as you'd like. Use printw for curses applications.
As for printing ?, those -1's sent to a terminal which expects UTF-8 would likely decide they're not valid UTF-8 and display the replacement character.

How could I achieve gotoxy() in gcc

I am using gcc in ubuntu.so, I compile and execute in terminal. But In a online programming contest, they require the output as shown in diagram.
For that, if I use TURBOC I can get it using conio.h using gotoxy() to get spiral format of output. But in Ubuntu , How could I achieve this?
Assuming because it is a contest and they don't want dependencies like ncurses you could try to do it in memory.
Set up 2 dimensional array of char - lines and columns - say 24x80. Write your own version of gotoxy() which assigns values into the proper cells. When done plotting, print out the array of lines.
Use the ncurses library.
Here's an example, adapted from http://www.paulgriffiths.net/program/c/srcs/curhellosrc.html
#include <stdlib.h>
#include <stdio.h>
#include <curses.h>
int main(void) {
WINDOW * mainwin;
/* Initialize ncurses */
if ( (mainwin = initscr()) == NULL ) {
fprintf(stderr, "Error initialising ncurses.\n");
exit(EXIT_FAILURE);
}
move(10, 15);
addch('X');
refresh();
getch();
delwin(mainwin);
endwin();
refresh();
return EXIT_SUCCESS;
}
Further information is available here: http://invisible-island.net/ncurses/ncurses-intro.html#stdscr
Aside of ANSI escape sequences you might wish to investigate ncurses:
http://www.gnu.org/s/ncurses/
It all ultimately depends upon the capabilities of the terminal running the program, not the actual host, language, or library. Consider what happens redirecting program output to a file or to a printer.
conio.h API is more to do with a fixed console, with Unix like systems you usual deal with terminals which can be more varied such as resizable X-Terminals.
Determine how many lines of output you need. Allocate an array of "char *" with one entry per line of output needed. When you place a number use "realloc()" to increase the size of the line and fill from the old end to the new end with spaces (if necessary); then put your number at the right place in that line (in memory).
After you've build an array of string in memory; do a for loop that prints each line (and frees the memory you allocated).
You don't need "gotoxy()" or anything to control cursor position.
Since it isn't here yet, I just wanted to say about an example using ANSI escape sequences as Steve-o mentioned.
void gotoxy(int x, int y)
{
printf("%c[%d;%df", 0x1B, y, x);
}
I got it from here.
0x1B is hexadecimal for 27 in decimal and is the ASCII for ESC. The escape sequences start with it
%m;%nf moves the cursor to row n, column m.
The ANSI escape sequences are used "to control the formatting, color, and other output options on video text terminals"

Is there a way to get text as soon as possible without waiting for a newline?

I'm using C. I wrote a very simpe program which prints back the input, using getchar() and putchar() or printf(). Is there any way to make it so as soon as the user types one key, the program registers it, without waiting for an Enter? Let me show:
Currently, if the user types "abc" and then presses Enter, the program prints "abc" and a newline and keeps waiting for more input. I want to make it so as soon as the user types "a", the program prints "a" and waits for more input. I'm not sure whether this has to be done inside the source code or if something has to be changed in the Windows command line.
Just in case, here's the source code:
#include <stdio.h>
int main()
{
int c;
while ((c = getchar()) != EOF) {
putchar(c);
}
return 0;
}
if you are using Visual Studio, there is a library called conio (#include <conio.h>) which defines a kbhit() function and getch().
otherwise, on Windows, there is still the possibility of using functions from the Windows SDK (ReadConsoleInput() and the like), but that would require a little bit more code (although, once done and if done properly, it can be reused any time you want)
If you're using Visual Studio, you can use getch().
In this simple case, the other answers should suit you fine.
The general solution is to disable line buffering. This depends on the particular console; the following example is Windows-only (untested):
#include <windows.h>
int main() {
HANDLE hConsole = GetStdHandle(STD_INPUT_HANDLE);
DWORD mode;
GetConsoleMode(hConsole, &mode);
SetConsoleMode(hConsole, mode & ~ENABLE_LINE_INPUT);
// ...
}
I assume that the standard C library functions are implemented in terms of ReadConsole and friends; if not, this might not even work. (I'm currently on Linux, so I cannot test this.)
On Linux you can take over the terminal:
#include <stdio.h>
#include <ctype.h>
#include <termios.h>
system("stty raw"); /* raw output to terminal, direct feedback */
system("clear"); /* clear screen */
printf("Press a key");
answer = getchar();
system("stty cooked"); /* revert back*/

Resources