I am trying to learn the PDcurses package in C but i keep getting this problem:
LINES value must be >= 2 and <= 1252: got -1
initscr(): Unable to create SP
My code:
#include <curses.h>
#include <stdlib.h>
#include <string.h>
int main()
{
FILE *lsofFile_p = popen("hostname", "r");
if (!lsofFile_p)
{
return -1;
}
int row,col;
char buffer[1024];
char *line_p = fgets(buffer, sizeof(buffer), lsofFile_p);
pclose(lsofFile_p);
initscr(); /* start the curses mode */
start_color();
init_pair(1,COLOR_GREEN,COLOR_BLACK);
init_pair(2,COLOR_BLUE,COLOR_BLACK);
getmaxyx(stdscr,row,col); /* get the number of rows and columns */
attron(COLOR_PAIR(1));
mvprintw(row/2,(col-strlen(line_p)-26)/2,"Your computer name is : ");
attroff(COLOR_PAIR(1));
attron(COLOR_PAIR(2)|A_BOLD);
printw("%s",line_p);
/* print the message at the center of the screen */
attroff(COLOR_PAIR(2)|A_BOLD);
wrefresh(stdscr);
system("pause");
endwin();
}
This works fine in Linux with ncurses instead of curses. If i simply try printing Hello world, it works too. So I have no idea where it is going wrong or how to fix it.
I am using MinGW gcc for compiling and I've got PDCurses installed from there too. I am running the code on Windows Terminal.
The error message indicates that PDcurses was unable to get the screen size from the Windows console. This may mean that it failed to figure out what type of terminal you are using (Windows console? Something else?). You may be able to get past this by setting the LINES environment variable to the correct value for your screen.
PDCurses tries to get this info by calling the windows function GetConsoleScreenBufferInfoEx in kernel32.dll, which should be pretty independent of what you're using compiler/terminal/whatnot, as long as you do have some kind of terminal window (not running headless)
Related
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.
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;
}
I read that command prompt has added support for ansi escape sequences. However, when I tried to run a program that was working fine on a linux terminal it did not color properly in cmd.
#include <stdio.h>
#define ANSI_BLUE "\x1b[32m"
#define ANSI_DEF "\x1b[0m"
int main() {
printf(ANSI_BLUE "Test" ANSI_DEF);
return 0;
}
But the output I recieve when I gcc and run the exe is:
[32mTest[0m
Is this a problem with the code, compiler or cmd?
How ansi escapes are handled are terminal dependent, and since cmd is your current terminal, that what decides what to do with those escapes.
Basically, what happens when you call printf, it just sends bytes to stdout. The terminal reads stdout and decides what to do with it.
The problem here has absolutely nothing to do with the compiler. If it is your code or cmd depends on how you view things. If you're using a HP printer with a Dell printer driver, is the problem with the printer or the driver? None of them. They just don't match.
Obviously, your terminal cannot handle those escapes, so if you want to print with color, you'll have to find another way.
These questions might be relevant:
colorful text using printf in C
C color text in terminal applications in windows
So what you can do on Windows is this:
#include <windows.h>
#include <stdio.h>
// Some old MinGW/CYGWIN distributions don't define this:
#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
#endif
static HANDLE stdoutHandle;
static DWORD outModeInit;
void setupConsole(void) {
DWORD outMode = 0;
stdoutHandle = GetStdHandle(STD_OUTPUT_HANDLE);
if(stdoutHandle == INVALID_HANDLE_VALUE) {
exit(GetLastError());
}
if(!GetConsoleMode(stdoutHandle, &outMode)) {
exit(GetLastError());
}
outModeInit = outMode;
// Enable ANSI escape codes
outMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
if(!SetConsoleMode(stdoutHandle, outMode)) {
exit(GetLastError());
}
}
void restoreConsole(void) {
// Reset colors
printf("\x1b[0m");
// Reset console mode
if(!SetConsoleMode(stdoutHandle, outModeInit)) {
exit(GetLastError());
}
}
int main(void) {
setupConsole();
puts("\x1b[31m\x1b[44mHello, World");
restoreConsole();
}
I also found this link about wrappers to be able to use ANSI escapes in Windows:
https://solarianprogrammer.com/2019/04/08/c-programming-ansi-escape-codes-windows-macos-linux-terminals/
As far as I know, there is no portable way of printing with colors in C.
Recently I've written a driver for a drawing tablet called the "Boogie Board RIP" to be able to use it as an input device for linux. It can be connected via usb to a computer. When the provided pen is near or touching the device's screen, it will send data telling where the pen is on the screen.
Basically the driver works great. I can write on it as if it was a wacom tablet.
At unpredictable times, the program will hang on the line below and the cursor on my computer screen will stay in place
fread(packet, sizeof(char), BYTES, f);
Where:
"packet" is an array of 8 bytes
"BYTES" is 8
"f" is a file opened in binary read (rb) mode. In my case it's /dev/usb/hiddev0
The basic program layout is a while loop that reads a byte at a time. Below is a mock-up of the much larger thing:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
char *path = argv[1];
unsigned char packet[8];
FILE *f = fopen(path, "rb");
int i;
while (1) {
fread(packet, sizeof(char), 8, f);
for(i=0;i<8;i++) {
printf("%x", packet[i]);
fflush(stdout);
}
}
}
I started to notice that my driver would "freeze" more often when I was running more things, like watching youtube, playing music... These aren't great examples. Basically I began to suspect it was related to CPU utilization. So I wrote the program below to test it:
#include <stdio.h>
int main() {
while(1) {
printf("a");
fflush(stdout);
fflush(stdout);
fflush(stdout);
fflush(stdout);
fflush(stdout);
fflush(stdout);
fflush(stdout);
}
}
Running this "infinite loop" program in a separate terminal while running the other program above in another terminal will result in harshly more frequent freezes. Basically the program will stop at the fread() line without fail within 2 seconds.
I learned that when the call to fread() doesn't get any data I can still read from the device with another instance of that program or simply printing out the contents of the file via sudo cat /dev/usb/hiddev0. The original process remains stuck while the new program will spit out the data coming from the device.
It seems as though the file simply closes. But that doesn't make sense because then fread would segfault on the next read. Looking for any ideas.
EDIT:
I solved this by using libusb to deal with reading from my device rather than trying to read directly from the device file.
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*/