Non canonical mode - c++

What's a simple way to using backspace in non canonical mode in linux terminal ?
It's part of code, when i set flags:
struct termios old_tio, new_tio;
/* get the terminal settings for stdin */
tcgetattr(STDIN_FILENO, &old_tio);
/* we want to keep the old setting to restore them a the end */
new_tio = old_tio;
/* disable canonical mode (buffered i/o) and local echo */
new_tio.c_lflag &=(~ICANON );/*& ~ECHOE );*/
/* set the new settings immediately */
tcsetattr(STDIN_FILENO,TCSANOW,&new_tio);
for(;1;) {
c = getchar();
switch(c) {...}
}
And when i press backspace i get an
^?
.
But i need to erase last symbol..
Thank you.

I don't think it's possible. According to the tcsetattr() man page (emphasis mine):
In noncanonical mode input is available immediately (without the user
having to type a line-delimiter character), and line editing is disabled.
Besides, if your program immediately receives every character you type, how can it be 'taken away' again?

Do this in your linux terminal and do your coding as usual it will not show ^? when u use backspace.
You can also add this in your .profile as permanent.
stty erase ^?

Related

Detect KeyDown KeyPress and KeyUp events in g++

I am editing a very old question of mine when I used to use turbo c++. So now I may not be able to explain exact behaviour of turboc++ compiler and hence will make some assumptions.
I know turbo c/c++ is not standard but am trying to achieve similar behaviour in g++ ubuntu.
Before I ask my question, it is necessary to quote the meaning of KeyDown, KeyPress and KeyUp event taken from one of the answers from Difference between the KeyDown Event, KeyPress Event and KeyUp Event in Visual Studio
The MSDN documentation states the order in which the three events occur fairly clearly:
Key events occur in the following order:
KeyDown
KeyPress
KeyUp
KeyDown is raised as soon as the user presses a key on the keyboard, while they're still holding it down.
KeyPress is raised for character keys (unlike KeyDown and KeyUp, which are also raised for noncharacter keys) while the key is pressed. This is a "higher-level" event than either KeyDown or KeyUp, and as such, different data is available in the EventArgs.
KeyUp is raised after the user releases a key on the keyboard.
Generally, you should handle the KeyUp event in your application. Actions should not be initiated in the UI until after the user releases the key. And since KeyUp is a lower-level event than KeyPress, you'll always have plenty of information at your fingertips about the key that was pressed, and it will even work for handling non-character keys.
NOTE : My question has nothing to do with MSDN. It was quoted only to get familiar with the KeyDown KeyPress and KeyUp events.
Now, getch in turbo c/c++ does not need the key to be released. The execution of getch(); gets completed as soon as one touches/presses any keyboard key(most probably only alphanumeric keys(assumption)).
Now a number of questions like this(Detecting when a key is released) and many other focus on windows plateform and not on g++ linux environment.
This question
C++ mutiple key input or key press/release events seems closest to my question but the question seems incomplete with information about neither the methodologies/code used to take input nor any error message(s).
Answer by Stephen Veiss with 29 up votes in the following question says that it is probably the closest equivalent.
https://stackoverflow.com/questions/1377403/alternative-function-in-iostream-h-for-getch-of-conio-h#:~:text=For%20getch()%2C%20int%20ch,getch%20does%20an%20unbuffered%20read.]
But it still needs the enter key to be pressed after typing input at the input terminal.
The first answer of the following question seems to correctly simulate getch() equivalent in g++(gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.12) ).
What is the equivalent to getch() & getche() in Linux?
#include<iostream>
using namespace std;
#include <termios.h>
#include <stdio.h>
static struct termios old, current;
/* Initialize new terminal i/o settings */
void initTermios(int echo)
{
tcgetattr(0, &old); /* grab old terminal i/o settings */
current = old; /* make new settings same as old settings */
current.c_lflag &= ~ICANON; /* disable buffered i/o */
if (echo) {
current.c_lflag |= ECHO; /* set echo mode */
} else {
current.c_lflag &= ~ECHO; /* set no echo mode */
}
tcsetattr(0, TCSANOW, &current); /* use these new terminal i/o settings now */
}
/* Restore old terminal i/o settings */
void resetTermios(void)
{
tcsetattr(0, TCSANOW, &old);
}
/* Read 1 character - echo defines echo mode */
char getch_(int echo)
{
char ch;
initTermios(echo);
ch = getchar();
resetTermios();
return ch;
}
/* Read 1 character without echo */
char getch(void)
{
return getch_(0);
}
/* Read 1 character with echo */
char getche(void)
{
return getch_(1);
}
/* Let's test it out */
int main(void) {
char c;
printf("(getche example) please type a letter: ");
c = getche();
printf("\nYou typed: %c\n", c);
printf("(getch example) please type a letter...");
c = getch();
printf("\nYou typed: %c\n", c);
return 0;
}
I have tested the above code. Touching any alphanumeric key completes execution of getch function but keystrokes of keys like CAPS_LOCK, SHIFT, CONTROL, ALT etc doesn't. Moreover, it forces us to use .h versions of header(stdio.h and termios.h), which I don't find commendable.
The following code
#include<iostream>
#include<ncurses.h>
using namespace std;
int main() {
cout<<"NIRBHAY KUMAR PANDEY"<<endl;
getch();
return 0;
}
compiles(g++ filename.cpp -lncurses) and runs successfully in my (Linux Mint 18.2 Cinnamon 64-bit, g++(gcc-5.4.0)) but gives following compilation errors in geeksforgeeks and hakerrank online compilers.
IN GEEKSFORGEEKS :
geeksforgeeks prog.cpp:2:20: fatal error: ncurses.h: No such file or directory.
IN HACKERRANK :
hakerrank /cc1ZsEbF.o: In function main': solution.cc:7: undefined reference to stdscr' solution.cc:7: undefined reference to `wgetch' collect2: error: ld returned 1 exit status Exit Status 255
Now my question is "are there any standard functions in standard headers in (Linux, g++) for detecting - KeyDown KeyPress and KeyUp events of all keys(including control keys and any key combination) of the keyboard - at the input terminal while waiting for input from the user ?
If yes, then a complete full running program will be appreciated.
(Note : I have achieved all this almost 12 years ago very easily by reading let us C 6th edition on turbo c/c++ compiler. I can recall that there were concept of ascii code and scan code. The book C++ primer 5th edition by Stanley B. Lippman has nothing to say anything about ascii code and scan code)

How to get macOS keyboard shortcuts set in System Preferences programmatically?

On macOS the key combination CMD+Backtick is used to cycle through the open windows of an application when using an english keyboard. On German keyboards for example the combination is CMD+<. This shortcut can even be configured using System Preferences -> Keyboard -> Shortcuts -> Keyboard -> Move focus to next window.
For my multi-window GUI application using FLTK I want to utilize this shortcut, but have no idea how to fetch the combination the user has set on his or her system. So what I'm looking for is a macOS system call that gives me the key combination that is used to Move focus to next window on this very Mac.
Of course if there would be a somewhat builtin way using FLTK I'd prefer that over having to use native system calls.
Googling for this issue is a nightmare ...
Update 08/10/2017
Öö's answer gave me some ideas for additional research. I've since learned that the preferences are stored in com.apple.symbolichotkeys, more precisely in key 27.
27 = {
enabled = 1;
value = {
parameters = (
98,
11,
524288
);
type = standard;
};
};
Parameter 1 (98): That's the ASCII code for "b". The first parameter has the ascii code of the shortcut used or 65535 if it's a non-ascii character.
Parameter 2 (11): That's the keyboard code for the kVK_ANSI_B (source). These codes are keyboard dependent. On a US keyboard, kVK_ANSI_Z is 0x06, while on a german keyboard it's 0x10.
Parameter 3 (524288): That's for the modifier key:
0x000000 => "No modifier",
0x020000 => "Shift",
0x040000 => "Control",
0x080000 => "Option",
0x100000 => "Command",
(0x80000 equals 524288.)
So my task just seems to be to parse the output of defaults read com.apple.symbolichotkeys, get the key combinations from the parameter dictionary, interpret those combinations correctly depending on the keyboard layout and use these information to set the callbacks in my FLTK app.
I can't test right now the answer ... but I would first try to popen the defaults command like:
HFILE file;
if (!(file = popen("defaults read NSGlobalDomain NSUserKeyEquivalents", "r")))
{
return nullptr;
}
const int MAX_BUF_SIZE = 512;
char temp[MAX_BUF_SIZE+1] = "";
while (fgets(temp, MAX_BUF_SIZE, file) > 0)
{
printf("%s",temp);
memset(temp, 0, MAX_BUF_SIZE+1);
}
pclose(file);
Here I just printf its output but you will likely want to parse it.

Clearing keyboard buffer in C++

I one part of my application I have used Sleep(5000) (I need to wait 5 sec)
The problem is that if the user presses any keyboard key during these 5 seconds, the keys will be read after sleep and it causes problems for my app.
How can I empty the buffer after sleep?
I tried cin.clear() and setbuf(stdin, NULL) but they can't clear the buffer if there is more than one character in the buffer.
The two functions you are using don't have the effect you expect them to have:
clear() doesn't affect the buffer at all but rather clears the error flags. That is, if there was an unsuccessful read a flag is set (std::ios_base::failbit). While any error flag is set (there are a few more), the stream won't attempt to read anything.
setbuf(0, 0) affects the stream's internal buffer to not exist (calls with non-null values have implementation-defined meaning which is typically "do nothing"). This is generally a Bad Idea because it causes the streams to be very slow. Also, the keys pressed by a user are probably not stored in this buffer anyway but rather in the operating systems input buffer until they are sent to application (there are platform specific ways to turn off the operating system input buffer, e.g., on POSIX you'd use tcsetattr() to set the input into non-canonical mode).
In either case, not having a buffer doesn't really help you anyway: The user may very well have typed valid input. The proper approach is to attempt reading the available input and, if this fails, to rid of the offending character (or characters). To this end you'd attempt to read the input and if it fails you'd clear() the stream and ignore() one or more characters (this example ignores an entire line; call ignore() without parameters to just ignore one character):
T value;
while (!(std::cin >> value)) {
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
You always need to verify that the input was successful anyway and the few extra lines are just adding a bit of recovery code.
The simplest way to clear the keyboard input buffer is
while(kbhit()) getch();
just put that code in your program wherever you want to clear your buffer .
headerfile needed for that is conio.h
This seems to work for Windows 10 compiled with Code::Blocks:
#include <conio.h>
/**
* clears keyboard buffer
*
* #author Shaun B
* #version 0.0.2
* #fixed 15-01-2016
*/
void clearKeyboardBuffer()
{
while (_kbhit())
{
_getche();
}
}
Then called from where is needed in your C++ script.

Unechoed string input in C++

I am writing a program in C++ where I am supposed to receive a string from user without displaying it on screen (for example: apassword). I tried using cin and gets to accept the string. But both will echo the characters entered by user in console.
So is there any function or any other way of doing it in C++?
How to avoid that data being read via cin shows up on the console depends very much on the console; it's certainly operating system dependant.
On Windows, you can use the SetConsoleMode function to enable/disable the echo for any file handle, including the standard input handle.
Something like
void enableStdinEcho( bool b ) {
HANDLE hStdin = ::GetStdHandle( STD_INPUT_HANDLE );
DWORD mode = 0;
::GetConsoleMode( hStdin, &mode );
if ( b ) {
mode |= ENABLE_ECHO_INPUT;
} else {
mode &= ~ENABLE_ECHO_INPUT;
}
::SetConsoleMode( hStdin, mode );
}
could probably be used to toggle the echo on stdin.
The C++ standard does not define a mechanism to do this. You have to rely on a platform specific library. For example with gcc/glibc use getpass
http://www.gnu.org/software/libc/manual/html_mono/libc.html#getpass
There might be other libraries that abstract these functions and provide a platform independent wrapper.
This is not a C++, iostream etc. question at all - it's specific to the terminal you're using.
See this question for ideas, and then ask a question specific to your terminal if it isn't covered there and you can't use ncurses.

How to input a char or a string without hitting the return key

I'm learning Objective C using Foundation and printing to the console. I would like to know (and how) if it is possible to input a char or string and it print out automatically without hitting the return key (or any key). Obviously the simple code below still requires the return key to be hit. I am aware this code is mixed between C & objC but I've been trying out differnet ideas. I am also trying to do this without using Ncurses. Thanks in advance.
char input [1];
NSLog(#"enter key:");
fgets(input, 1, stdin);
NSString *inputString = [[NSString alloc]initWithCString:input];
NSLog(#"Input = %s",input);
Ive just found a good answer as follows:
// Set terminal to raw mode
system("stty raw");
// Wait for single character
char input = getchar();
// Echo input:
// Reset terminal to normal "cooked" mode
system("stty cooked");
// And we're out of here
NSLog(#"INPUT = %c",input);
Read the manual for tcsetattr and tcgetattr. Look for the flags ICANON and IECHO, and check out the part about cfmakeraw. The documentation console_ioctl(4) and tty_ioctl(4) may be of further interest, for example to determine the size of the tty.
Have a look at http://pwilson.net/sample.html and search for kbhit.c . That function should work for you, though it's not been tested with Objective C.