The function _getch() behaves unexpectedly in git-bash terminal - c

I have been trying to figure out how it is possible to change the terminal's mode from "cooked" to "raw" using C and in a Git Bash terminal.
I have tried to execute the program with winpty and that makes that certain part of the program function as expected. However, it messes up the other parts, like clearing the screen with the control sequence \x1b[2J, and vice versa. Clearing the screen works perfectly when I am NOT executing the program with winpty.
I have also tried using system("clear") and system("cls") but with no luck. I have also tried to set the mode using the function _setmode(_fileno(stdin), _O_BINARY) but no such function seems to be working with Git Bash and more specifically MinTTY.
When I am using getch() nothing simply happens and I have to use CTRL+C to exit the program. However, it should exit the program when I press the 'i' character.
The code looks like this:
#include <windows.h>
#include <conio.h>
#include <stdio.h>
void clear_screen() {
printf("\\033\[2J");
printf("\\033\[1;1H");
fflush(stdout);
}
int main() {
#ifdef _WIN32
clear_screen();
while (1) {
char c = _getch();
if (c == 'i') {
exit(0);
}
}
#endif
#ifdef linux
#endif
}

Related

Removing some lines from screen after program start using printf format specifier or something

On this page it gives example that to clean the terminal screen I can use printf with \e[1;1H\e[2J
https://stackoverflow.com/a/42500322/4808760
This is the code given there
#ifdef _WIN32
#include <conio.h>
#else
#include <stdio.h>
#define clrscr() printf("\e[1;1H\e[2J")
#endif
I don't understand what is "\e[1;1H\e[2J". Is this whole new thing or just another way of doing format specifier for printf and scanf (can I use it with scanf too)?
What is \e , [1 , ; ,1H , \e and [2J in above string feed for printf in clrscr() macro?
And if I have this code:
int main(){
printf("Buffered 1\n");
printf("Buffered 2\n");
printf("Buffered 3\n");
clrscr();// Prints to screen
return 0;
}
output:
user:
The problem is with the code in this question clrscr() is that it removes everything from screen. What if I like to remove only printf text Buffered 1\n and Buffered 3\n or whichever possible text from terminal screen. I have also seen in output of programs install in Linux with terminal text. I am using Ubuntu.

Sleep() function in C not working on hp non-stop

I am trying something in C on hp-nonstop(tandem),
As part my task is to wait for sometime.
I try to use the
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main()
{
int i;
for(i=0;i<10;i++)
{
printf("Something");
sleep(5);
printf("Something");
fflush(stdout);
}
}
It's compiling without any problem,
While running it is giving ABENDED: each time different no.
The result calling sleep() from guardian environment is undefined. That might be leading to ABEND that you mentioned. If you want to wait for some time in guardian hp-nonstop environment, you should call DELAY(). It takes centi-seconds as arguments. So if you want to add delay of 5 seconds, you should call it as DELAY (500). You also need to include the header #include<cextdecs(DELAY)>

Sleep | warning implicit declaration of function `sleep'?

I am learning C.
In this program
I use sleep function to slowdown a count down.
My text book doesn't specify a library I should include to use the sleep function.
So I use it without including any special library for it and it works.
But it gives me this warning message in codeblocks.
I tried to include <windows.h> but still the same warning message appears.
warning D:\Project\C language\trial8\trial8.c|19|warning: implicit
declaration of function `sleep'|
And here is my code.
#include <stdio.h>
int main()
{
int start;
do
{
printf("Please enter the number to start\n");
printf("the countdown (1 to 100):");
scanf("%d",&start);
}
while(start<1 || start>100);
do
{
printf("T-minus %d\n",start);
start--;
sleep(3000);
}
while(start>0);
printf("Zero!\n Go!\n");
return(0);
}
I want to know what does the warning message mean? How important is it? Is there anything that I should do about it? Note that the program works anyway.
The issue is in the libraries (header files):
on Windows:
#include <windows.h> and Sleep(1000); => 1000 milliseconds
on Linux:
#include <unistd.h> and sleep(1); => 1 second
The function sleep is not part of C programming language. So, C compiler needs a declaration/prototype of it so that it can get to know about about number of arguments and their data types and return data type of the function. When it doesn't find it, it creates an Implicit Declaration of that function.
In Linux, sleep has a prototype in <unistd.h> and in windows, there is another function Sleep which has a prototype in <windows.h> or <synchapi.h>.
You can always get away with including header, if you explicitly supply the prototype of the function before using it. It is useful when you need only few functions from a header file.
The prototype of Sleep function in C on windows is:
VOID WINAPI Sleep(_In_ DWORD dwMilliseconds);
Remember, it is always a good practice to supply the prototype of the function being used either by including the appropriate header file or by explicitly writing it. Even, if you don't supply it, compiler will just throw a warning most of the time and it will make an assumption which in most cases will be something that you don't want. It is better to include the header file as API might change in future versions of the Library.
Windows doesn't have the sleep function. Instead, it has Sleep, which takes the number of milliseconds to sleep:
VOID WINAPI Sleep(
_In_ DWORD dwMilliseconds
);
You'll need to either #include <windows.h> or #include <synchapi.h>, depending on the version of Windows you're running. See MSDN for more details.
Update in 2022:
As it is stated on the Linux man page here we need to include unistd.h and should do fine for all OS.
#include <stdio.h>
#include <unistd.h>
int main()
{
sleep(1); /* sleep for 1 second*/
printf("END\n");
return 0;
}
To make it more cross-platform, try this:
#ifdef _WIN32
#include <Windows.h>
#else
#include <unistd.h>
#endif

Wrong printing when using signal handler

I have encountered problems on signal handling when writing a shell-like program on C.
Here is the simplified version of my code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#define SIZE 255
void sig_handler(int sig){
if (sig == SIGINT)
printf("\n[shell]$\n");
}
int main()
{
char input[SIZE];
printf("[shell]$");
signal(SIGINT,sig_handler);
while( gets(input) != NULL ){
// code of the shell including command interpreter and command execution
printf("[shell]$");
}
return 0;
}
When I run the program and try out SIGINT with command - "cat", the output shows as the following:
[shell]$ ^C (ctrl+C pressed for the first time)
[shell]$
^C (the input position go to the next line, which is unwanted)
[shell]$
cat (I want it in the same line with [shell]$)
^C
[shell]$
[shell]$ (duplicate printing occurs)
I have tried to modify the function void sig_handler(int sig) by deleting the second \n. However, the situation becomes worse than before. The program doesn't automatically trigger the signal event on the first pressing of ctrl+C.
To clarify my problem, here are the two questions I ask:
1. How to make the input position on the same line with [shell]$ ?
2. How to solve the duplicate printing problem ?
What #zneak said is true, you can use fflush and delete the second \n in sig_handler,
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#define SIZE 255
void sig_handler(int sig){
if (sig == SIGINT)
printf("\n[shell]$");
fflush(stdout);
}
int main()
{
char input[SIZE];
printf("[shell]$");
fflush(stdout);
signal(SIGINT,sig_handler);
while( gets(input) != NULL ){
// code of the shell including command interpreter and command execution
printf("[shell]$");
}
return 0;
}
First and foremost, printing from signal handler is a bad idea. Signal handler is like an interrupt handler - it happens asynchronously, it could be raised while being inside your standard library code and calling another stdlib routine might mess up with non-reentrant internals of it (imagine catching SIGINT while inside of printf() in your loop).
If you really want to output something from within, you better use raw write() call to stderr file descriptor.

How do I clear the screen in C? [duplicate]

This question already has answers here:
Clearing output of a terminal program Linux C/C++
(7 answers)
Clear screen in C and C++ on UNIX-based system?
(10 answers)
Closed 9 years ago.
I want to clear all the text that is on the screen.
I have tried using:
#include <stdlib.h>
sys(clr);
Thanks in advance!
I'm using OS X 10.6.8. Sorry for the confusion!
You need to check out curses.h. It is a terminal (cursor) handling library, which makes all supported text screens behave in a similar manner.
There are three released versions, the third (ncurses) is the one you want, as it is the newest, and is ported to the most platforms. The official website is here, and there are a few good tutorials.
#include <curses.h>
int main(void)
{
initscr();
clear();
refresh();
endwin();
}
The best way to clear the screen is to call the shell via system(const char *command) in stdlib.h:
system("clear"); //*nix
or
system("cls"); //windows
Then again, it's always a good idea to minimize your reliance on functions that call the system/environment, as they can cause all kinds of undefined behavior.
Windows:
system("cls"); // missing 's' has been replaced
Unix:
system("clear");
You can wrap this in a single, more portable piece of code like so:
void clearscr(void)
{
#ifdef _WIN32
system("cls");
#elif defined(unix) || defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))
system("clear");
//add some other OSes here if needed
#else
#error "OS not supported."
//you can also throw an exception indicating the function can't be used
#endif
}
Note the check for unix is pretty expansive. This should also detect OS X, which is what you're using.
The availability of this function or similar ones like clrscn() are very system dependent and not portable.
You could keep it really simple and roll you own:
#include <stdio.h>
void clearscr ( void )
{
for ( int i = 0; i < 50; i++ ) // 50 is arbitrary
printf("\n");
}

Resources