I’m trying to create a program that waits either until the user inputs a certain keyword or until a certain amount of time has elapsed.
I’ve succeeded in that, but now, if I start to type in an entry, wait until cout flushes, and then attempt to delete the unsubmitted input, instead of moving the cursor back and overwriting, the console prints ^R and goes to a new line.
Is there a way I can fix that?
Here’s my code. I’m using Visual Studio Code on Mac OS 10.13.6:
what happens in a simple program with your tools:
int main()
{
string s;
cin >> s; //type something and then try to backspace or whatever you were trying to do above
}
if this does the same thing, your console delete interface is not working correctly or not supported. I havent done a lot of mac code since osx but ive seen a few posts where its console is weird at random times.
if it works properly, your threading above is likely scrambling the streams somehow, I don't see where, but the threads share the same cin / cout and may somehow get it into a bad state trying to run concurrently. You could try a mutex around the cins ?
I wrote an even simpler program which proved what I suspected, it has nothing to do with threads. I was hoping that moving the cursor would allow the program to handle backspaces better.
The end location of the cursor appears to be irrelevant.
#include<iostream>
#include<chrono>
void pauseRun(int time)
{
std::chrono::steady_clock::time_point t = std::chrono::steady_clock::now();
while(std::chrono::steady_clock::now() - t < std::chrono::milliseconds(time));
return;
}
int main(void)
{
std::cout << "Type something, but don't press enter. " << std::endl;
pauseRun(5000);
std::cout << "\nNow press backspace. Do you get ^R?" << std::endl;
pauseRun(5000);
std::cout << "Let's try something different. \nPress enter to continue" << std::endl;
while(std::cin.get() != '\n');
std::cout << "This time, type 'abcd' in the command line, then press backspace once, but \ndo not enter it: \t" << std::flush;
pauseRun(5000);
I suspected the same, that it was not the threading.
All I can offer at the moment is that I see this in unix sometimes when a keyboard command sends a control sequence and the console reads the key press as ctrl+something instead of handling the action. Some of those are keys (like the arrow keys) and some are control commands (oops, tried to paste with standard ctrl+v, not supported, get rubbish chars in console).
You could try trapping the ^R sequence and when you see it, purge it from the buffer. But that seems like the last resort approach. I honestly do not know the proper approach.
you said delete: did you mean backspace, or the del key?
Ive found that backspace is almost always supported, delete, maybe not.
you may be able to search the buffer with peek or something, if you see those letters, delete them with ignore or whatever it is? There are tools to manipulate it, but I haven't done a ton of this.. not sure exactly what steps you need there.
You can test in fhere's input and then do the read if there's some, or and check the time if there isn't.
On a Mac? You can use select() with STDIN_FILENO to check if a read is available. It's best wrap all that stuff into your own kbhit() function, so the code will work in the same way.
Since you are on nix, add the gnu getline library to your program. The terminal is probably already using it on your behalf, but either way it will make your life easier. It is very customizable in code.