When I use the normal std::cin or std::cin.get() or std::getline() functions, I get unwanted (but understandable) behaviour.
When you use the arrow keys to move back for example, you don't move back, but you input something like "^[[D" into the console.
Is there a way to make the std input function more like, let's say the Python terminal environment?
Thanks in advance!
No, you cannot do it with the standard library. The only approximation is outputting the backspace character \b and hope it does the right thing in the user's environment.
You will need to use either system APIs or libraries like readline or ncurses.
Related
It is not uncommon to see a command-line program that prompts the user to enter a string to be processed in some way by the program. But is it possible to create a program that does this, and has a default value already there at the prompt - so that if the user wants to use the default value, they need only press Enter? (But if the user wants to use a different value, they will have to set about editing the pre-populated string - which might mean holding down backspace to delete it and then typing something else.)
Provisos:
Needs to work on Windows. Well, for my purposes it needs to work on Windows. You can suggest a solution that only works on other OSes if you like, but I won't accept your answer.
Needs to use only what is provided by the standard library.
It's not sufficient to just say, "leave input empty to use the default value" - that's merely a workaround.
I've seen versions of this question that are specific to other languages, but not one for C++.
One can do it using just the standard library.
But one cannot do it with just the guarantees provided by the standard library.
What you need to have, for any solution, is a way to control the terminal (which implies a guarantee about being connected to a terminal, and knowledge of the idiosyncrasies in controlling said terminal.
Unfortunately, the windows console window is not a proper terminal, which can be controlled that way.
In Linux, I can use tcsetattr, but I want to write a portable C++ program that can turn echo of cin on and off (for entering a password). Is there something in std::io* that supports this?
Unfortunately there is no portable way to disable console echo, so you have to use OS specific API. You can use preprocessor to write portable program, but you would have to write separate code for supported OS and wrap it into #ifdef condition. Another solution would be to use portable library if such one exists, that would do this under the hood for you.
No, there is not. C/C++'s IO libraries are based around the "stream" model, where input comes from some random source of characters (generally the console) and output is similarly sent to some random character target. In a sense, it isn't C/C++ doing the echoing at all -- it's the console system -- so there's no way for it to control whether the echoing occurs.
I have been using the very very old Turbo C++ 3.0 compiler.
During the usage of this compiler, I have become used to functions like getch(), getche() and most importantly clrscr().
Now I have started using Visual C++ 2010 Express. This is causing a lot of problems, as most of these functions (I found this out now) are non-standard and are not available in Visual C++.
What am I to do now?
Always try to avoid them if possible or try their alternatives :
for getch() --- cin.get()
clrscr -- system("cls") // try avoiding the system commands. check : [System][1]
And for any others you can search for them .
The real question is what you are trying to do, globally.
getch and clrscr have never been portable. If you're trying
to create masks or menus in a console window, you should look
into curses or ncurses: these offer a portable solution for
such things. If it's just paging, you can probably get away
with simple outputing a large number of '\n' (for clrscr),
and std::cin.get() for getch. (But beware that this will only
return once the user has entered a new line, and will only read
one character of the line, leaving the rest in the buffer. It
is definitely not a direct replacement for getch. In fact,
std::getline or std::cin::ignore might be better choices.)
Edit:
Adding some more possiblities:
First, as Joachim Pileborg suggested in his comment, if
portability is an issue, there may be platform specific
functions for much of what you are trying to do. If all you're
concerned about is Windows (and it probably is, since system(
"cls" ) and getch() don't work elsewhere), then his comment
may be a sufficient answer.
Second, for many consoles (including xterm and the a console
window under Windows), the escape sequence "\x1b""2J" should
clear the screen. (Note that you have to enter it as two
separate string literals, since otherwise, it would be
interpreted as two characters, the first with the impossible hex
value of 0x1b2.) Don't forget about possible issues of
redirection and flushing, however.
Finally, if you're doing anything non-trivial, you should look
into curses (or ncurses, they're the same thing, but with
different implementations). It's a bit more effort to put into
action (you need explicit initialization, etc.), but it has
a getch function which does exactly what you want, and it also
has functions for explicitly positionning the curser, etc. which
may also make your code simpler. (The original curses was
developed to support the original vi editor, at UCB. Any
editor like task not being developed in its own window would
benefit enormously from it.)
Well,
People, i have found the one best solution that can be used everywhere.
I simply googled the definitions of clrscr() and gotoxy() and created a header file and added these definitions to it. Thus, i can include this file and do everything that i was doing prior.
But, i have a query too.
windows.h is there in the definition. suppose i compile the file and make a exe file. Then will i be able to run it on a linux machine?
According to me the answer has to be yes. But please tell me if i am wrong and also tell me why i am wrong.
I have been doing some reading, and I see that I can use getch() to get a keystroke. What I have seen is that this is considered bad practice, however I have seen conflicting opinions. I am writing a console application for my class, and would like to be able to move a marker(*) around the screen based on the arrow keys being pressed. Is getch() the right way to go about this, or is there a better method to capture it. I want them to just be able to push the arrow, not need to push enter or anything. I don't need the code specifically, I just want to know if I should avoid getch(), and if so, what functions are there for this type of idea.
getch() is not a standard function in either C or C++. It's found in some obsolete compilers, such as Turbo C and it's also defined in certain commonly used libraries such as curses, but in any case it's a C function, not C++. For C++ you should probably just stick with standard C++ I/O. If you can't do this for some reason then go for the most portable option, e.g. curses.
You want to read from the terminal in non-canonical mode. Use tcsetattr() to turn off the ICANON flag.
Use getch() if it works. Why not?
On Windows you can use pdcurses: http://pdcurses.sourceforge.net/, that is compatible with ncurses.
I'm having trouble working this out. Basically my program has a standard input, I want to modify this so if the user enters a space it automatically replaces it with a / whilst they're typing. I have no idea how i'd even go about doing this or if it is even possible so I am grateful for any help either way.
I believe that if you want to do manipulation of the text on the console like that, you're going to need a library such as ncurses.
You would need to turn off echoing of the characters typed and then echo them yourself after validating them, replacing characters as necessary. There are different ways to do that for different operating systems (e.g. Linux vs. Windows), and even more unfortunately, that can mean taking control of the entire screen just for this simple function since the backspace/delete key would need to be handled properly (even over multiple lines if necessary). In short, you're taking control away from the user while making yourself responsible for the common functionality that a user would expect, which makes things rather difficult because you can't know how certain terminals behave, not to mention issues with locales. It's easier just to replace the characters yourself after the input is received or issue an error message, depending on your purpose and specific use-case.
Edit: PDCurses is cross-platform, so you might try that if you're still interested. It's easier than coding for specific platforms.