www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How do I read one character from stdin? (getc in C)

reply Fer22f <fer22f gmail.com> writes:
Hello! I'm starting to make some simple command line programs and 
one thing I miss from C is a function for getting one character 
from the input. This is for example, an "Press Any Key Program".

Anyone that has more experience can point me into a solution that 
is not deprecated? I haven't even researched about the deprecated 
options but looked into all free available D books I could find 
and I only found ways to get entire lines (even if it's just one 
character I still need to press enter).
Nov 14 2015
next sibling parent reply BBaz <b2.temp gmx.com> writes:
On Saturday, 14 November 2015 at 13:33:49 UTC, Fer22f wrote:
 Hello! I'm starting to make some simple command line programs 
 and one thing I miss from C is a function for getting one 
 character from the input. This is for example, an "Press Any 
 Key Program".

 Anyone that has more experience can point me into a solution 
 that is not deprecated? I haven't even researched about the 
 deprecated options but looked into all free available D books I 
 could find and I only found ways to get entire lines (even if 
 it's just one character I still need to press enter).
--- import std.stdio; void main(string[] args) { char c; stdin.readf("%c", &c); writeln(c); }
Nov 14 2015
parent Fer22f <fer22f gmail.com> writes:
On Saturday, 14 November 2015 at 13:53:50 UTC, BBaz wrote:
     stdin.readf("%c", &c);
     writeln(c);
Nope. In *nix this works? In Windows I still need to hit enter, and the character is the first one of the line I entered.
Nov 14 2015
prev sibling next sibling parent Nicholas Wilson <iamthewilsonator hotmail.com> writes:
On Saturday, 14 November 2015 at 13:33:49 UTC, Fer22f wrote:
 Hello! I'm starting to make some simple command line programs 
 and one thing I miss from C is a function for getting one 
 character from the input. This is for example, an "Press Any 
 Key Program".

 Anyone that has more experience can point me into a solution 
 that is not deprecated? I haven't even researched about the 
 deprecated options but looked into all free available D books I 
 could find and I only found ways to get entire lines (even if 
 it's just one character I still need to press enter).
Well you can always call C in d i.e. import core.stdc.stdio; void main(string[] args) { char c = getc(); }
Nov 14 2015
prev sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Saturday, 14 November 2015 at 13:33:49 UTC, Fer22f wrote:
 Anyone that has more experience can point me into a solution 
 that is not deprecated? I haven't even researched about the 
 deprecated options but looked into all free available D books I 
 could find and I only found ways to get entire lines (even if 
 it's just one character I still need to press enter).
That's because the operating system buffers it and needs to be turned off. The getc in stdio.h works the same way, though if you had a getch in conio.h or something like that, it is different. You might be able to pull that from D, but since it isn't technically standard C, it isn't available on all systems. Notably, it is pretty common on Windows, but requires an add-on library like ncurses on Linux. (which is commonly installed, but not automatically linked) Well, bottom line is you need a fair chunk of code to do this (well, like 20 lines for minimal functionality, it isn't that bad but still a bit involved), whether written yourself or pulled from a library. You might try taking my terminal library: https://github.com/adamdruppe/arsd/blob/master/terminal.d Download that file and add it to your build like this: dmd yourfile.d terminal.d Example usage: import terminal; void main() { auto terminal = Terminal(ConsoleOutputType.linear); auto input = RealTimeConsoleInput(&terminal, ConsoleInputFlags.raw); terminal.writeln("Press any key to exit."); input.getch(); terminal.writeln("Bye!"); } The first two lines have the library do various setup tasks like turning off line buffering. Once those two are set though the next three lines are pretty ordinary and should work like you want. It is kinda a pain to pass these to functions... you'd want to do pass them around as pointers. Their destructors reset the terminal to its default state so your program exits cleanly.
Nov 14 2015
parent reply Fer22f <fer22f gmail.com> writes:
On Saturday, 14 November 2015 at 20:05:45 UTC, Adam D. Ruppe 
wrote:
 Notably, it is pretty common on Windows, but requires an add-on 
 library like ncurses on Linux.

 https://github.com/adamdruppe/arsd/blob/master/terminal.d
Yea, I always though it would be kinda different between platforms but getc worked in VSC++ so I assumed it would work in D too. And you just pointed out this entire world of ncurses to me, I couldn't see myself not using some kind of API for building "graphical" terminal interfaces... Thanks for the insight. I will take a look at your library later!
Nov 14 2015
parent Adam D. Ruppe <destructionator gmail.com> writes:
BTW I was slightly inaccurate: it doesn't *require* a library to 
do this, you just need to disable buffering. But the getc 
function itself doing that is dependent on some library 
implementation.

On Windows for example you need to call this function and turn 
off line input:

https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033%28v=vs.85%29.aspx

On Unix it is this family of functions:

http://linux.die.net/man/3/tcsetattr


But regardless my library does this for you, so does ncurses, and 
a few others out there.
Nov 14 2015